diff --git a/.clang-tidy b/.clang-tidy index d6a8f0f31..8556f60a1 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,8 +1,48 @@ --- -Checks: '-*,clang-analyzer-*,clang-diagnostic-*,readability-*,modernize-*,boost-*,bugprone-*,cppcoreguidelines-*,google-*,hicpp-*,performance-*,readability-*,-google-readability-namespace-comments,-readability-inconsistent-declaration-parameter-name,-readability-braces-around-statements,-hicpp-signed-bitwise,-google-runtime-references,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-readability-magic-numbers,-hicpp-explicit-conversions,-hicpp-uppercase-literal-suffix,-readability-uppercase-literal-suffix,-hicpp-no-array-decay,-hicpp-special-member-functions,-bugprone-narrowing-conversions,-modernize-use-nodiscard,-google-readability-braces-around-statements,-hicpp-braces-around-statements,-bugprone-suspicious-semicolon,-readability-named-parameter,-hicpp-named-parameter,-modernize-use-trailing-return-type,-cppcoreguidelines-non-private-member-variables-in-classes,-cppcoreguidelines-pro-bounds-constant-array-index' +Checks: > + -*, + clang-analyzer-*, + clang-diagnostic-*, + readability-*, + modernize-*, + boost-*, + bugprone-*, + cppcoreguidelines-*, + google-*, + hicpp-*, + performance-*, + readability-*, + -google-readability-namespace-comments, + -readability-inconsistent-declaration-parameter-name, + -readability-braces-around-statements, + -hicpp-signed-bitwise, + -google-runtime-references, + -cppcoreguidelines-avoid-magic-numbers, + -cppcoreguidelines-pro-bounds-array-to-pointer-decay, + -readability-magic-numbers, + -hicpp-explicit-conversions, + -hicpp-uppercase-literal-suffix, + -readability-uppercase-literal-suffix, + -hicpp-no-array-decay, + -hicpp-special-member-functions, + -bugprone-narrowing-conversions, + -modernize-use-nodiscard, + -google-readability-braces-around-statements, + -hicpp-braces-around-statements, + -bugprone-suspicious-semicolon, + -readability-named-parameter, + -hicpp-named-parameter, + -modernize-use-trailing-return-type, + -cppcoreguidelines-non-private-member-variables-in-classes, + -cppcoreguidelines-pro-bounds-constant-array-index, + -modernize-concat-nested-namespaces, + # TODO(themarpe) - Gradually bring back errors #WarningsAsErrors: 'modernize-*,cppcoreguidelines-*,boost-*,performance-*,google-build-using-namespace,readability-else-after-return,google-readability-todo' -WarningsAsErrors: 'bugprone-throw-keyword-missing' +WarningsAsErrors: > + bugprone-throw-keyword-missing, + bugprone-unchecked-optional-access, + HeaderFilterRegex: 'core/.*\.hpp' AnalyzeTemporaryDtors: false FormatStyle: .clang-format diff --git a/.github/workflows/main.workflow.yml b/.github/workflows/main.workflow.yml index 3b07b0018..acc08966e 100644 --- a/.github/workflows/main.workflow.yml +++ b/.github/workflows/main.workflow.yml @@ -6,16 +6,16 @@ on: branches: - main - develop - - gen2 - - gen2_develop + - rvc3_support + - rvc3_develop tags: - 'v*' pull_request: branches: - main - develop - - gen2 - - gen2_develop + - rvc3_support + - rvc3_develop jobs: @@ -63,10 +63,10 @@ jobs: strategy: matrix: os: [macos-latest, windows-latest, ubuntu-latest] - cmake: ['3.10.x', ''] # Older version (Ubuntu 18.04) and newest + cmake: ['3.14.x', ''] # Older version (Ubuntu 18.04) and newest exclude: - os: windows-latest - cmake: '3.10.x' + cmake: '3.14.x' steps: - name: Cache .hunter folder @@ -109,7 +109,7 @@ jobs: echo "OpenCV_DIR=C:\tools\opencv\build" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - name: Build (old CMake, gcc/Clang) - if: matrix.cmake == '3.10.x' && matrix.os != 'windows-latest' + if: matrix.cmake == '3.14.x' && matrix.os != 'windows-latest' run: | cmake -H. -Bbuild -D'CMAKE_BUILD_TYPE=Release' -D'HUNTER_CONFIGURATION_TYPES=Release' -D'DEPTHAI_BUILD_EXAMPLES=ON' -D'DEPTHAI_BUILD_TESTS=ON' ${{ env.CMAKE_ARGS }} cmake --build build --config Release -- -j4 @@ -122,7 +122,7 @@ jobs: # cmake --build build - name: Build (newest CMake) - if: matrix.cmake != '3.10.x' + if: matrix.cmake != '3.14.x' run: | cmake -S . -B build -D CMAKE_BUILD_TYPE=Release -D HUNTER_CONFIGURATION_TYPES=Release -D DEPTHAI_BUILD_EXAMPLES=ON -D DEPTHAI_BUILD_TESTS=ON ${{ env.CMAKE_ARGS }} cmake --build build --parallel 4 --config Release @@ -181,6 +181,9 @@ jobs: echo "CMAKE_GENERATOR=Visual Studio 17 2022" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append echo "CMAKE_GENERATOR_PLATFORM=${{ matrix.platform }}" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + - name: Setup cmake + uses: jwlawson/actions-setup-cmake@v1.13 + - name: Configure ${{ matrix.build-type }}, shared ${{ matrix.shared }}, ${{ matrix.platform }} run: cmake -S . -B build -D BUILD_SHARED_LIBS=${{ matrix.shared}} -D CMAKE_BUILD_TYPE=${{ matrix.build-type }} -D CMAKE_INSTALL_PREFIX=$GITHUB_WORKSPACE/depthai_install ${{ env.CMAKE_ARGS }} diff --git a/.github/workflows/python-docker-hub.yml b/.github/workflows/python-docker-hub.yml new file mode 100644 index 000000000..d2566de32 --- /dev/null +++ b/.github/workflows/python-docker-hub.yml @@ -0,0 +1,100 @@ +name: Publish Docker image +on: + workflow_dispatch: + push: + branches: + - main + - develop + tags: + - 'v*' +jobs: + + build: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, [Linux, ARM], [Linux, ARM64]] + include: + - os: ubuntu-latest + arch: amd64 + - os: [Linux, ARM] + arch: armv7 + - os: [Linux, ARM64] + arch: armv8 + steps: + - name: Clean the workspace + uses: docker://alpine + with: + args: /bin/sh -c "rm -rf /github/workspace/.* || rm -rf /github/workspace/*" + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: recursive + - name: Login to DockerHub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USER }} + password: ${{ secrets.DOCKERHUB_PASS }} + + - name: Set Image Name (development) + id: name + if: startsWith(github.ref, 'refs/tags/v') != true + run: echo "LUXONIS_IMAGE_TAG=${{ github.sha }}-${{ matrix.arch }}" >> $GITHUB_ENV + + - name: Set Image Name (release) + if: startsWith(github.ref, 'refs/tags/v') == true + run: echo "LUXONIS_IMAGE_TAG=${GITHUB_REF#refs/*/}-${{ matrix.arch }}" >> $GITHUB_ENV + + - name: Build and push + uses: docker/build-push-action@v3 + with: + push: true + file: bindings/python/ci/Dockerfile + tags: luxonis/depthai-library:${{ env.LUXONIS_IMAGE_TAG }} + + - name: Cleanup the created image + run: docker image rm luxonis/depthai-library:${{ env.LUXONIS_IMAGE_TAG }} + + upload: + needs: [build] + name: Combine into a single multi-arch image and upload tags + runs-on: ubuntu-latest + steps: + + - name: Login to DockerHub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USER }} + password: ${{ secrets.DOCKERHUB_PASS }} + + - name: Get Version + id: vars + run: echo ::set-output name=short_ref::${GITHUB_REF#refs/*/} + + - name: Build and push (development) + if: startsWith(github.ref, 'refs/tags/v') != true + run: | + docker manifest create \ + luxonis/depthai-library:${{ github.sha}} \ + --amend luxonis/depthai-library:${{ github.sha }}-amd64 \ + --amend luxonis/depthai-library:${{ github.sha }}-armv7 \ + --amend luxonis/depthai-library:${{ github.sha }}-armv8 + # Push + docker manifest push luxonis/depthai-library:${{ github.sha }} + + - name: Build and push (release) + if: startsWith(github.ref, 'refs/tags/v') == true + run: | + docker manifest create \ + luxonis/depthai-library:${{ steps.vars.outputs.short_ref }} \ + --amend luxonis/depthai-library:${{ steps.vars.outputs.short_ref }}-amd64 \ + --amend luxonis/depthai-library:${{ steps.vars.outputs.short_ref }}-armv7 \ + --amend luxonis/depthai-library:${{ steps.vars.outputs.short_ref }}-armv8 + # Push + docker manifest push luxonis/depthai-library:${{ steps.vars.outputs.short_ref }} + docker manifest create \ + luxonis/depthai-library:latest \ + --amend luxonis/depthai-library:${{ steps.vars.outputs.short_ref }}-amd64 \ + --amend luxonis/depthai-library:${{ steps.vars.outputs.short_ref }}-armv7 \ + --amend luxonis/depthai-library:${{ steps.vars.outputs.short_ref }}-armv8 + docker manifest push luxonis/depthai-library:latest diff --git a/.github/workflows/python-main.yml b/.github/workflows/python-main.yml new file mode 100644 index 000000000..af2ad70d0 --- /dev/null +++ b/.github/workflows/python-main.yml @@ -0,0 +1,534 @@ +name: Depthai Python CI/CD + +# Controls when the action will run. Triggers the workflow on push + +################################### +# WARNING ######################### +# as self-hosted runners are used, and security policy for them has not been yet determined by GitHub +# pay close attention to not enable workflows on pull_request events +# TLDR: do NOT add 'pull_request' here for the time being +on: + workflow_dispatch: + push: + branches: + - v3_develop + tags: + - 'v*' + +################################### +################################### + +env: + CMAKE_WINDOWS_SDK_VERSION: '10.0.18362.0' + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + + # Job which builds docstrings for the rest of the wheel builds + build-docstrings: + runs-on: ubuntu-latest + steps: + - name: Cache .hunter folder + uses: actions/cache@v3 + with: + path: ~/.hunter + key: hunter-ubuntu-latest-v3-develop + - name: List .hunter cache directory + run: ls -a -l ~/.hunter/_Base/ || true + - uses: actions/checkout@v3 + with: + submodules: 'recursive' + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: 3.8 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + sudo apt install libusb-1.0-0-dev + python -m pip install -r bindings/python/docs/requirements_mkdoc.txt + - name: Configure project + run: cmake -S . -B build -DDEPTHAI_BUILD_PYTHON=ON -DDEPTHAI_PYTHON_FORCE_DOCSTRINGS=ON -DDEPTHAI_PYTHON_DOCSTRINGS_OUTPUT="$PWD/bindings/python/docstrings/depthai_python_docstring.hpp" + - name: Build target 'pybind11_mkdoc' + run: cmake --build build --target pybind11_mkdoc --parallel 4 + - name: Upload docstring artifacts + uses: actions/upload-artifact@v3 + with: + name: docstrings + path: bindings/python/docstrings/ + retention-days: 1 + + + # Build and test bindings + pytest: + needs: build-docstrings + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + runs-on: ${{ matrix.os }} + steps: + - name: Print home directory + run: echo Home directory inside container $HOME + + - name: Cache .hunter folder + if: matrix.os != 'windows-latest' + uses: actions/cache@v3 + with: + path: ~/.hunter/ + key: hunter-pytest-${{ matrix.os }}-v3-develop + - name: Cache .hunter folder + if: matrix.os == 'windows-latest' + uses: actions/cache@v3 + with: + path: C:/.hunter/ + key: hunter-pytest-${{ matrix.os }}-v3-develop + + - uses: actions/checkout@v3 + with: + submodules: 'recursive' + + - uses: actions/download-artifact@v3 + with: + name: 'docstrings' + path: bindings/python/docstrings + - name: Specify docstring to use while building the wheel + run: echo "DEPTHAI_PYTHON_DOCSTRINGS_INPUT=$PWD/bindings/python/docstrings/depthai_python_docstring.hpp" >> $GITHUB_ENV + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: "3.10" + + - name: Install dependencies (Ubuntu) + if: matrix.os == 'ubuntu-latest' + run: | + python -m pip install --upgrade pip + sudo apt install libusb-1.0-0-dev + + - name: Install dependencies (MacOS) + if: matrix.os == 'macos-latest' + run: | + python -m pip install --upgrade pip + brew install libusb + + - name: Install pytest + run: | + python -m pip install pytest numpy + + - name: Compile + run: | + cmake -S . -B build -DDEPTHAI_BUILD_PYTHON=ON -D CMAKE_BUILD_TYPE=Release -D DEPTHAI_PYTHON_DOCSTRINGS_INPUT=$PWD/bindings/python/docstrings/depthai_python_docstring.hpp -D DEPTHAI_PYTHON_ENABLE_TESTS=ON + cmake --build build --parallel 4 + - name: Test + run: | + cmake --build build --target pytest --config Release + + + # This job builds wheels for armhf arch (RPi) + build-linux-armhf: + needs: build-docstrings + strategy: + matrix: + rpi-os: [rpi-buster, rpi-bullseye, rpi-bookworm] + runs-on: ${{ matrix.rpi-os }} + steps: + - name: Print home directory + run: echo Home directory inside container $HOME + - uses: actions/checkout@v3 + with: + submodules: 'recursive' + + - uses: actions/download-artifact@v3 + with: + name: 'docstrings' + path: bindings/python/docstrings + - name: Specify docstring to use while building the wheel + run: echo "DEPTHAI_PYTHON_DOCSTRINGS_INPUT=$PWD/bindings/python/docstrings/depthai_python_docstring.hpp" >> $GITHUB_ENV + + - name: Append build hash if not a tagged commit + if: startsWith(github.ref, 'refs/tags/v') != true + run: echo "BUILD_COMMIT_HASH=${{github.sha}}" >> $GITHUB_ENV + - name: Building wheel + run: cd bindings/python && python3 -m pip wheel . -w ./wheelhouse/ --verbose + - name: Auditing wheels and adding armv6l tag (Running on RPi, binaries compiled as armv6l) + run: | + cd bindings/python + python3 -m pip install -U wheel auditwheel + for whl in wheelhouse/*.whl; do auditwheel repair "$whl" --plat linux_armv7l -w wheelhouse/preaudited/; done + for whl in wheelhouse/preaudited/*.whl; do python3 -m wheel tags --platform-tag +linux_armv6l "$whl"; done + mkdir -p wheelhouse/audited/ + for whl in wheelhouse/preaudited/*linux_armv6l*.whl; do cp "$whl" wheelhouse/audited/$(basename $whl); done + - name: Archive wheel artifacts + uses: actions/upload-artifact@v3 + with: + name: audited-wheels + path: bindings/python/wheelhouse/audited/ + - name: Deploy wheels to artifactory (if not a release) + if: startsWith(github.ref, 'refs/tags/v') != true + run: cd bindings/python && bash ./ci/upload-artifactory.sh + env: + ARTIFACTORY_URL: ${{ secrets.ARTIFACTORY_URL }} + ARTIFACTORY_USER: ${{ secrets.ARTIFACTORY_USER }} + ARTIFACTORY_PASS: ${{ secrets.ARTIFACTORY_PASS }} + + + # This job builds wheels for Windows x86_64 arch + build-windows-x86_64: + needs: build-docstrings + runs-on: windows-latest + strategy: + matrix: + python-version: [3.6, 3.7, 3.8, 3.9, '3.10', '3.11', '3.12'] + python-architecture: [x64, x86] + fail-fast: false + steps: + - name: Cache .hunter folder + uses: actions/cache@v3 + with: + path: C:/.hunter + key: hunter-msvc-v3-develop + - uses: actions/checkout@v3 + with: + submodules: 'recursive' + + - uses: actions/download-artifact@v3 + with: + name: 'docstrings' + path: bindings/python/docstrings + - name: Specify docstring to use while building the wheel + run: echo "DEPTHAI_PYTHON_DOCSTRINGS_INPUT=$PWD/bindings/python/docstrings/depthai_python_docstring.hpp" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + + - name: Select Windows SDK + run: echo "CMAKE_ARGS=-DCMAKE_SYSTEM_VERSION=${{ env.CMAKE_WINDOWS_SDK_VERSION }}" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + architecture: ${{ matrix.python-architecture }} + - name: Append build hash if not a tagged commit + if: startsWith(github.ref, 'refs/tags/v') != true + run: echo "BUILD_COMMIT_HASH=${{github.sha}}" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + - name: Install dependencies + run: | + python -m pip install --upgrade pip + - name: Building wheels + run: cd bindings/python && python -m pip wheel . -w ./wheelhouse/audited/ --verbose + - name: Archive wheel artifacts + uses: actions/upload-artifact@v3 + with: + name: audited-wheels + path: bindings/python/wheelhouse/audited/ + - name: Deploy wheels to artifactory (if not a release) + if: startsWith(github.ref, 'refs/tags/v') != true + run: cd bindings/python && bash ./ci/upload-artifactory.sh + env: + ARTIFACTORY_URL: ${{ secrets.ARTIFACTORY_URL }} + ARTIFACTORY_USER: ${{ secrets.ARTIFACTORY_USER }} + ARTIFACTORY_PASS: ${{ secrets.ARTIFACTORY_PASS }} + + # This job builds wheels for macOS x86_64 arch + build-macos-x86_64: + needs: build-docstrings + runs-on: macos-latest + strategy: + matrix: + python-version: [3.6, 3.7, 3.8, 3.9, '3.10', '3.11', '3.12'] + fail-fast: false + steps: + - name: Cache .hunter folder + uses: actions/cache@v3 + with: + path: ~/.hunter + key: hunter-macos-latest-v3-develop + - name: List .hunter cache directory + run: | + ls -a -l ~/.hunter/_Base/ || true + echo "PATH=$PATH" + + - uses: actions/checkout@v3 + with: + submodules: 'recursive' + + - uses: actions/download-artifact@v3 + with: + name: 'docstrings' + path: bindings/python/docstrings + - name: Specify docstring to use while building the wheel + run: echo "DEPTHAI_PYTHON_DOCSTRINGS_INPUT=$PWD/bindings/python/docstrings/depthai_python_docstring.hpp" >> $GITHUB_ENV + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: Append build hash if not a tagged commit + if: startsWith(github.ref, 'refs/tags/v') != true + run: echo "BUILD_COMMIT_HASH=${{github.sha}}" >> $GITHUB_ENV + - name: Install dependencies + run: | + python -m pip install --upgrade pip + brew install libusb + python -m pip install delocate + - name: Building wheels + run: cd bindings/python && python -m pip wheel . -w ./wheelhouse/ --verbose + - name: Auditing wheels + run: cd bindings/python && ci/repair-whl-macos.sh `pwd`/wheelhouse/* `pwd`/wheelhouse/audited + - name: Archive wheel artifacts + uses: actions/upload-artifact@v3 + with: + name: audited-wheels + path: bindings/python/wheelhouse/audited/ + - name: Deploy wheels to artifactory (if not a release) + if: startsWith(github.ref, 'refs/tags/v') != true + run: cd bindings/python && bash ./ci/upload-artifactory.sh + env: + ARTIFACTORY_URL: ${{ secrets.ARTIFACTORY_URL }} + ARTIFACTORY_USER: ${{ secrets.ARTIFACTORY_USER }} + ARTIFACTORY_PASS: ${{ secrets.ARTIFACTORY_PASS }} + + # This job builds wheels for macOS arm64 arch + build-macos-arm64: + needs: build-docstrings + runs-on: [self-hosted, macOS, ARM64] + steps: + # Cached locally on runner + # - name: Cache .hunter folder + # uses: actions/cache@v3 + # with: + # path: ~/.hunter + # key: hunter-macos-latest + - name: List .hunter cache directory + run: | + ls -a -l ~/.hunter/_Base/ || true + echo "PATH=$PATH" + + - uses: actions/checkout@v3 + with: + submodules: 'recursive' + + - uses: actions/download-artifact@v3 + with: + name: 'docstrings' + path: bindings/python/docstrings + - name: Specify docstring to use while building the wheel + run: echo "DEPTHAI_PYTHON_DOCSTRINGS_INPUT=$PWD/bindings/python/docstrings/depthai_python_docstring.hpp" >> $GITHUB_ENV + + - name: Append build hash if not a tagged commit + if: startsWith(github.ref, 'refs/tags/v') != true + run: echo "BUILD_COMMIT_HASH=${{github.sha}}" >> $GITHUB_ENV + + # - name: Build and install depthai-core + # run: | + # echo "MACOSX_DEPLOYMENT_TARGET=11.0" >> $GITHUB_ENV + # cmake -S depthai-core/ -B build_core -D CMAKE_BUILD_TYPE=Release -D CMAKE_TOOLCHAIN_FILE=$PWD/cmake/toolchain/pic.cmake + # cmake --build build_core --target install --parallel 4 + # echo "DEPTHAI_INSTALLATION_DIR=$PWD/build_core/install/" >> $GITHUB_ENV + + - name: Build wheels + run: cd bindings/python && for PYBIN in {9..12}; do "python3.${PYBIN}" -m pip wheel . -w wheelhouse/ --verbose; done + + - name: Auditing wheels + run: | + cd bindings/python + delocate-wheel -v -w wheelhouse/audited wheelhouse/*.whl + + - name: Archive wheel artifacts + uses: actions/upload-artifact@v3 + with: + name: audited-wheels + path: bindings/python/wheelhouse/audited/ + - name: Deploy wheels to artifactory (if not a release) + if: startsWith(github.ref, 'refs/tags/v') != true + run: cd bindings/python && bash ./ci/upload-artifactory.sh + env: + ARTIFACTORY_URL: ${{ secrets.ARTIFACTORY_URL }} + ARTIFACTORY_USER: ${{ secrets.ARTIFACTORY_USER }} + ARTIFACTORY_PASS: ${{ secrets.ARTIFACTORY_PASS }} + + # This job builds wheels for x86_64 arch + build-linux-x86_64: + needs: build-docstrings + runs-on: ubuntu-latest + container: + image: quay.io/pypa/manylinux2014_x86_64:2024-01-08-eb135ed + env: + PLAT: manylinux2014_x86_64 + steps: + - name: Cache .hunter folder + uses: actions/cache@v3 + with: + path: ~/.hunter + key: hunter-x86_64-v3-develop + - uses: actions/checkout@v3 + with: + submodules: 'recursive' + - name: Installing libusb1-devel dependency + run: yum install -y --disableplugin=fastestmirror libusb1-devel + - name: Installing cmake dependency + run: | + cd bindings/python + /opt/python/cp38-cp38/bin/python3.8 -m pip install cmake + ln -s /opt/python/cp38-cp38/bin/cmake /bin/ + - name: Create folder structure + run: cd bindings/python && mkdir -p wheelhouse/audited/ + + - uses: actions/download-artifact@v3 + with: + name: 'docstrings' + path: bindings/python/docstrings + - name: Specify docstring to use while building the wheel + run: echo "DEPTHAI_PYTHON_DOCSTRINGS_INPUT=$PWD/bindings/python/docstrings/depthai_python_docstring.hpp" >> $GITHUB_ENV + + - name: Build and install depthai-core + run: | + cmake -S . -B build_core -D CMAKE_BUILD_TYPE=Release -D CMAKE_TOOLCHAIN_FILE=$PWD/cmake/toolchain/pic.cmake + cmake --build build_core --target install --parallel 4 + echo "DEPTHAI_INSTALLATION_DIR=$PWD/build_core/install/" >> $GITHUB_ENV + + - name: Append build hash if not a tagged commit + if: startsWith(github.ref, 'refs/tags/v') != true + run: echo "BUILD_COMMIT_HASH=${{github.sha}}" >> $GITHUB_ENV + + - name: Building source distribution + run: | + cd bindings/python + /opt/python/cp38-cp38/bin/python3.8 setup.py sdist --formats=gztar + mv dist/* wheelhouse/audited/ + - name: Build wheels + run: cd bindings/python && for PYBIN in /opt/python/cp3{6..12}*/bin; do "${PYBIN}/pip" wheel . -w ./wheelhouse/ --verbose; done + - name: Audit wheels + run: cd bindings/python && for whl in wheelhouse/*.whl; do auditwheel repair "$whl" --plat $PLAT -w wheelhouse/audited/; done + - name: Archive wheel artifacts + uses: actions/upload-artifact@v3 + with: + name: audited-wheels + path: bindings/python/wheelhouse/audited/ + - name: Deploy wheels to artifactory (if not a release) + if: startsWith(github.ref, 'refs/tags/v') != true + run: cd bindings/python && bash ./ci/upload-artifactory.sh + env: + ARTIFACTORY_URL: ${{ secrets.ARTIFACTORY_URL }} + ARTIFACTORY_USER: ${{ secrets.ARTIFACTORY_USER }} + ARTIFACTORY_PASS: ${{ secrets.ARTIFACTORY_PASS }} + + # This job builds wheels for ARM64 arch + build-linux-arm64: + needs: build-docstrings + runs-on: [self-hosted, linux, ARM64] + container: + image: quay.io/pypa/manylinux2014_aarch64:2024-01-08-eb135ed + env: + PLAT: manylinux2014_aarch64 + # Mount local hunter cache directory, instead of transfering to Github and back + volumes: + - /.hunter:/github/home/.hunter + steps: + - uses: actions/checkout@v3 + with: + submodules: 'recursive' + - name: Installing libusb1-devel dependency + run: yum install -y --disableplugin=fastestmirror libusb1-devel + - name: Installing cmake dependency + run: | + cd bindings/python + /opt/python/cp38-cp38/bin/python3.8 -m pip install cmake + ln -s /opt/python/cp38-cp38/bin/cmake /bin/ + - name: Create folder structure + run: cd bindings/python && mkdir -p wheelhouse/audited/ + + - uses: actions/download-artifact@v3 + with: + name: 'docstrings' + path: bindings/python/docstrings + - name: Specify docstring to use while building the wheel + run: echo "DEPTHAI_PYTHON_DOCSTRINGS_INPUT=$PWD/bindings/python/docstrings/depthai_python_docstring.hpp" >> $GITHUB_ENV + + - name: Build and install depthai-core + run: | + cmake -S . -B build_core -D CMAKE_BUILD_TYPE=Release -D CMAKE_TOOLCHAIN_FILE=$PWD/cmake/toolchain/pic.cmake + cmake --build build_core --target install --parallel 4 + echo "DEPTHAI_INSTALLATION_DIR=$PWD/build_core/install/" >> $GITHUB_ENV + + - name: Append build hash if not a tagged commit + if: startsWith(github.ref, 'refs/tags/v') != true + run: echo "BUILD_COMMIT_HASH=${{github.sha}}" >> $GITHUB_ENV + - name: Building wheels + run: cd bindings/python && for PYBIN in /opt/python/cp3{6..12}*/bin; do "${PYBIN}/pip" wheel . -w ./wheelhouse/ --verbose; done + - name: Auditing wheels + run: cd bindings/python && for whl in wheelhouse/*.whl; do auditwheel repair "$whl" --plat $PLAT -w wheelhouse/audited/; done + - name: Archive wheel artifacts + uses: actions/upload-artifact@v3 + with: + name: audited-wheels + path: bindings/python/wheelhouse/audited/ + - name: Deploy wheels to artifactory (if not a release) + if: startsWith(github.ref, 'refs/tags/v') != true + run: cd bindings/python && bash ./ci/upload-artifactory.sh + env: + ARTIFACTORY_URL: ${{ secrets.ARTIFACTORY_URL }} + ARTIFACTORY_USER: ${{ secrets.ARTIFACTORY_USER }} + ARTIFACTORY_PASS: ${{ secrets.ARTIFACTORY_PASS }} + + release: + if: startsWith(github.ref, 'refs/tags/v') + needs: [pytest, build-linux-armhf, build-windows-x86_64, build-macos-x86_64, build-macos-arm64, build-linux-x86_64, build-linux-arm64] + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + with: + submodules: 'recursive' + + - uses: actions/setup-python@v4 + with: + python-version: '3.8' + + - name: Check if version matches + run: python3.8 -c 'import find_version as v; exit(0) if "${{ github.ref_name }}" == f"v{v.get_package_version()}" else exit(1)' + + # Deploy to PyPi and Artifactory. Only when a commit is tagged + deploy: + if: startsWith(github.ref, 'refs/tags/v') + needs: [release] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + submodules: 'recursive' + - uses: actions/download-artifact@v3 + with: + name: audited-wheels + path: bindings/python/wheelhouse/audited/ + - name: List files + run: ls -lah + - name: Run deploy to PyPi + run: cd bindings/python && bash ./ci/upload-pypi.sh + env: + PYPI_SERVER: ${{ secrets.PYPI_SERVER }} + PYPI_USER: ${{ secrets.PYPI_USER }} + PYPI_PASSWORD: ${{ secrets.PYPI_PASSWORD }} + - name: Run deploy to Artifactory + run: cd bindings/python && bash ./ci/upload-artifactory-release.sh + env: + ARTIFACTORY_URL: ${{ secrets.ARTIFACTORY_URL }} + ARTIFACTORY_USER: ${{ secrets.ARTIFACTORY_USER }} + ARTIFACTORY_PASS: ${{ secrets.ARTIFACTORY_PASS }} + + notify_hil_workflow_linux_x86_64: + needs: [build-linux-x86_64] + runs-on: ubuntu-latest + steps: + - name: Dispatch an action and get the run ID + uses: codex-/return-dispatch@v1 + id: return_dispatch + with: + token: ${{ secrets.HIL_CORE_DISPATCH_TOKEN }} # Note this is NOT GITHUB_TOKEN but a PAT + ref: main # or refs/heads/target_branch + repo: depthai-core-hil-tests + owner: luxonis + workflow: regression_test.yml + workflow_inputs: '{"commit": "${{ github.ref }}", "parent_url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"}' + workflow_timeout_seconds: 300 # was 120 Default: 300 + + - name: Release + run: echo "https://github.com/luxonis/depthai-core-hil-tests/actions/runs/${{steps.return_dispatch.outputs.run_id}}" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/python-test-install-dependencies.yml b/.github/workflows/python-test-install-dependencies.yml new file mode 100644 index 000000000..1e427c7b9 --- /dev/null +++ b/.github/workflows/python-test-install-dependencies.yml @@ -0,0 +1,64 @@ + name: python bindings OS Support + + on: + workflow_dispatch: + push: + paths: + - 'bindings/python/docs/source/_static/install_dependencies.sh' + - 'bindings/python/examples/install_requirements.py' + pull_request: + paths: + - 'bindings/python/docs/source/_static/install_dependencies.sh' + - 'bindings/python/examples/install_requirements.py' + + jobs: + test_linux: + runs-on: ubuntu-latest + strategy: + matrix: + container_image: ["fedora:34", "fedora:35", "fedora:36", "ubuntu:18.04", "ubuntu:20.04", "ubuntu:22.04", "ubuntu:22.10"] + container: + image: ${{ matrix.container_image }} + steps: + - uses: actions/checkout@v3 + - name: Install sudo + if: startsWith(matrix.container_image, 'fedora') == true + run: yum update -y && yum install -y sudo + - name: Install sudo + if: startsWith(matrix.container_image, 'ubuntu') == true + run: apt-get update -qq && apt-get -qq install sudo + - name: Install dependencies + run: | + ln -snf /usr/share/zoneinfo/UTC /etc/localtime && echo UTC > /etc/timezone # Otherwise tzdata installer prompts for user input + sed '/udevadm control --reload-rules && sudo udevadm trigger/d' bindings/python/docs/source/_static/install_dependencies.sh > tmp_script.sh # Doesn't work on docker + bash tmp_script.sh + - name: Install example requirements + run: | + python3 bindings/python/examples/install_requirements.py + test_macos: + strategy: + matrix: + os: ["macos-11", "macos-12"] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v3 + - name: Install dependencies + run: | + sed '/udevadm control --reload-rules && sudo udevadm trigger/d' bindings/python/docs/source/_static/install_dependencies.sh > tmp_script.sh + bash tmp_script.sh + - name: Install example requirements + run: | + python3 bindings/python/examples/install_requirements.py + test_windows: + runs-on: windows-latest + steps: + - uses: actions/checkout@v3 + - name: Download chocolatey + shell: pwsh + run: Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) + - name: Install dependencies + shell: pwsh + run: choco install cmake git python --version 3.10 -y + - name: Install example requrirements + run: | + python bindings/python/examples/install_requirements.py diff --git a/.gitignore b/.gitignore index 4dd08b34f..7c8ff8ad3 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,12 @@ depthai-cpp/build/ #ci wheelhouse/ calib*.json +#depthai c++ core library +depthai-core/.vscode/ +depthai-core/build/ + +# builds +_builds/ #git *.orig *_REMOTE_* diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 000000000..2257bb8d2 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,14 @@ +variables: + GIT_SUBMODULE_STRATEGY: recursive + +build:armhf: + tags: + - luxonis-armhf + image: registry.gitlab.com/luxonis/depthai-crosscompile/debian-buster + stage: build + script: + - python3 -m pip wheel . -w wheelhouse/ + - for whl in wheelhouse/*.whl; do auditwheel repair "$whl" --plat "linux_armv7l" -w wheelhouse/audited/; done + artifacts: + paths: + - wheelhouse/audited/ \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index 07c85c94a..03b7b447a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,12 @@ -[submodule "shared/depthai-shared"] - path = shared/depthai-shared - url = ../depthai-shared.git [submodule "shared/depthai-bootloader-shared"] path = shared/depthai-bootloader-shared url = ../depthai-bootloader-shared.git +[submodule "3rdparty/xtensor"] + path = 3rdparty/xtensor + url = https://github.com/xtensor-stack/xtensor +[submodule "3rdparty/xtl"] + path = 3rdparty/xtl + url = https://github.com/xtensor-stack/xtl +[submodule "bindings/python/external/xtensor-python"] + path = bindings/python/external/xtensor-python + url = https://github.com/xtensor-stack/xtensor-python.git diff --git a/3rdparty/xtensor b/3rdparty/xtensor new file mode 160000 index 000000000..8ef0ee649 --- /dev/null +++ b/3rdparty/xtensor @@ -0,0 +1 @@ +Subproject commit 8ef0ee649fcd7476242af1d2072b45364036937d diff --git a/3rdparty/xtl b/3rdparty/xtl new file mode 160000 index 000000000..e697c91e2 --- /dev/null +++ b/3rdparty/xtl @@ -0,0 +1 @@ +Subproject commit e697c91e2a3ac571d120d2b093fb3b250d060a7d diff --git a/CMakeLists.txt b/CMakeLists.txt index ecd5a4850..f5604dcf2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,8 +35,8 @@ endif() include("cmake/HunterGate.cmake") HunterGate( - URL "https://github.com/cpp-pm/hunter/archive/v0.23.322.tar.gz" - SHA1 "cb0ea1f74f4a2c49a807de34885743495fccccbe" + URL "https://github.com/cpp-pm/hunter/archive/v0.24.18.tar.gz" + SHA1 "1292e4d661e1770d6d6ca08c12c07cf34a0bf718" LOCAL # Local config for dependencies ) @@ -46,7 +46,7 @@ if(WIN32) endif() # Create depthai project -project(depthai VERSION "2.24.0" LANGUAGES CXX C) +project(depthai VERSION "2.25.0" LANGUAGES CXX C) get_directory_property(has_parent PARENT_DIRECTORY) if(has_parent) set(DEPTHAI_VERSION ${PROJECT_VERSION} PARENT_SCOPE) @@ -96,11 +96,10 @@ option(DEPTHAI_INSTALL "Enable install target for depthai-core targets" ON) # Debug option set(DEPTHAI_XLINK_LOCAL "" CACHE STRING "Path to local XLink source to use instead of Hunter") -set(DEPTHAI_SHARED_LOCAL "" CACHE STRING "Path to local depthai-shared source to use instead of submodule") set(DEPTHAI_BOOTLOADER_SHARED_LOCAL "" CACHE STRING "Path to local depthai-bootloader-shared source to use instead of submodule") # Enable backward stack printing on crash -if(ANDROID) +if(ANDROID OR EMSCRIPTEN) # Backward not supported currently on Android set(DEPTHAI_ENABLE_BACKWARD OFF CACHE BOOL "" FORCE) else() @@ -165,6 +164,8 @@ endif() ### Get and find dependencies +# Specify optional dependencies +option(DEPTHAI_XTENSOR_SUPPORT "Enable optional xtensor support" ON) # Include project dependencies set(DEPTHAI_DEPENDENCY_INCLUDE "" CACHE FILEPATH "Optional cmake file to append to dependency processing, e.g. additional find_package()") include(depthaiDependencies) @@ -172,9 +173,10 @@ include(depthaiDependencies) # Add threads preference set(THREADS_PREFER_PTHREAD_FLAG ON) -# Add depthai-shared, and definitions that it is PC side -include(${CMAKE_CURRENT_LIST_DIR}/shared/depthai-shared.cmake) - +# TODO Remove shared naming +set(DEPTHAI_SHARED_3RDPARTY_INCLUDE + ${CMAKE_CURRENT_LIST_DIR}/include/3rdparty/ +) # Add depthai-bootloader-shared include(${CMAKE_CURRENT_LIST_DIR}/shared/depthai-bootloader-shared.cmake) @@ -188,8 +190,6 @@ set(TARGET_CORE_ALIAS core) # Create core library add_library(${TARGET_CORE_NAME} - # depthai-shared sources - "${DEPTHAI_SHARED_SOURCES}" # depthai-bootloader-shared sources "${DEPTHAI_BOOTLOADER_SHARED_SOURCES}" # sources @@ -197,12 +197,15 @@ add_library(${TARGET_CORE_NAME} src/device/DeviceBase.cpp src/device/DeviceBootloader.cpp src/device/DataQueue.cpp - src/device/CallbackHandler.cpp + # src/device/CallbackHandler.cpp src/device/CalibrationHandler.cpp src/device/Version.cpp src/pipeline/Pipeline.cpp src/pipeline/AssetManager.cpp + src/pipeline/MessageQueue.cpp src/pipeline/Node.cpp + src/pipeline/ThreadedNode.cpp + src/pipeline/DeviceNode.cpp src/pipeline/node/XLinkIn.cpp src/pipeline/node/XLinkOut.cpp src/pipeline/node/ColorCamera.cpp @@ -218,6 +221,8 @@ add_library(${TARGET_CORE_NAME} src/pipeline/node/VideoEncoder.cpp src/pipeline/node/DetectionNetwork.cpp src/pipeline/node/Script.cpp + src/pipeline/node/Pool.cpp + src/pipeline/node/Benchmark.cpp src/pipeline/node/SpatialDetectionNetwork.cpp src/pipeline/node/SystemLogger.cpp src/pipeline/node/SpatialLocationCalculator.cpp @@ -227,10 +232,17 @@ add_library(${TARGET_CORE_NAME} src/pipeline/node/EdgeDetector.cpp src/pipeline/node/SPIIn.cpp src/pipeline/node/FeatureTracker.cpp + src/pipeline/node/ToF.cpp src/pipeline/node/DetectionParser.cpp + src/pipeline/node/Sync.cpp + src/pipeline/node/test/MyProducer.cpp + src/pipeline/node/test/MyConsumer.cpp src/pipeline/node/UVC.cpp + src/pipeline/datatype/DatatypeEnum.cpp + src/pipeline/node/PointCloud.cpp src/pipeline/datatype/Buffer.cpp src/pipeline/datatype/ImgFrame.cpp + src/pipeline/datatype/ImgTransformations.cpp src/pipeline/datatype/EncodedFrame.cpp src/pipeline/datatype/ImageManipConfig.cpp src/pipeline/datatype/CameraControl.cpp @@ -238,6 +250,7 @@ add_library(${TARGET_CORE_NAME} src/pipeline/datatype/ImgDetections.cpp src/pipeline/datatype/SpatialImgDetections.cpp src/pipeline/datatype/SystemInformation.cpp + src/pipeline/datatype/SystemInformationS3.cpp src/pipeline/datatype/StreamMessageParser.cpp src/pipeline/datatype/SpatialLocationCalculatorData.cpp src/pipeline/datatype/SpatialLocationCalculatorConfig.cpp @@ -250,6 +263,9 @@ add_library(${TARGET_CORE_NAME} src/pipeline/datatype/TrackedFeatures.cpp src/pipeline/datatype/FeatureTrackerConfig.cpp src/pipeline/datatype/ToFConfig.cpp + src/pipeline/datatype/BenchmarkReport.cpp + src/pipeline/datatype/PointCloudConfig.cpp + src/pipeline/datatype/PointCloudData.cpp src/pipeline/datatype/MessageGroup.cpp src/utility/H26xParsers.cpp src/utility/Initialization.cpp @@ -259,12 +275,20 @@ add_library(${TARGET_CORE_NAME} src/utility/Environment.cpp src/utility/XLinkGlobalProfilingLogger.cpp src/utility/Logging.cpp + src/utility/Checksum.cpp + src/utility/matrixOps.cpp src/utility/EepromDataParser.cpp src/xlink/XLinkConnection.cpp src/xlink/XLinkStream.cpp src/openvino/OpenVINO.cpp src/openvino/BlobReader.cpp src/bspatch/bspatch.c + src/device/DeviceGate.cpp + src/utility/ArchiveUtil.cpp + src/nn_archive/NNArchive.cpp + src/nn_archive/NNArchiveConfig.cpp + src/nn_archive/NNArchiveBlob.cpp + src/nn_archive/NNArchiveConfigHelper.cpp ) add_library("${PROJECT_NAME}::${TARGET_CORE_ALIAS}" ALIAS ${TARGET_CORE_NAME}) # Specify that we are building core @@ -283,38 +307,34 @@ if(DEPTHAI_CLANG_TIDY) target_clangtidy_setup(${TARGET_CORE_NAME}) endif() -# Set compiler features (c++14), and disables extensions (g++14) -set_property(TARGET ${TARGET_CORE_NAME} PROPERTY CXX_STANDARD 14) +# Set compiler features (c++17), and disables extensions (g++17) +set_property(TARGET ${TARGET_CORE_NAME} PROPERTY CXX_STANDARD 17) set_property(TARGET ${TARGET_CORE_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) set_property(TARGET ${TARGET_CORE_NAME} PROPERTY CXX_EXTENSIONS OFF) -# Add interface transitive property (C++14) +# Add interface transitive property (C++17) if(${CMAKE_VERSION} VERSION_LESS "3.8.0") target_compile_features(${TARGET_CORE_NAME} INTERFACE cxx_generic_lambdas) else() - target_compile_features(${TARGET_CORE_NAME} INTERFACE cxx_std_14) + target_compile_features(${TARGET_CORE_NAME} INTERFACE cxx_std_17) endif() +# Minimal supported macOS SDK version for C++17 support with std::filesystem +set(CMAKE_OSX_DEPLOYMENT_TARGET 10.15) # First specify options option(DEPTHAI_BUILD_TESTS "Build tests" OFF) option(DEPTHAI_BUILD_EXAMPLES "Build examples - Requires OpenCV library to be installed" OFF) +option(DEPTHAI_BUILD_PYTHON "Build python bindings" OFF) option(DEPTHAI_BUILD_DOCS "Build documentation - requires doxygen to be installed" OFF) option(DEPTHAI_OPENCV_SUPPORT "Enable optional OpenCV support" ON) +option(DEPTHAI_PCL_SUPPORT "Enable optional PCL support" ON) +# Specify support for FW +option(DEPTHAI_ENABLE_DEVICE_FW "Enable MyriadX Device FW" ON) +option(DEPTHAI_ENABLE_DEVICE_BOOTLOADER_FW "Enable MyriadX Device Bootloader FW" ON) +option(DEPTHAI_ENABLE_DEVICE_RVC3_FW "Enable RVC3 Device FW" ON) +option(DEPTHAI_ENABLE_DEVICE_RVC4_FW "Enable RVC4 Device FW" ON) option(DEPTHAI_BINARIES_RESOURCE_COMPILE "Compile Depthai device side binaries into library" ON) -option(DEPTHAI_USB2_PATCH_ONLY_MODE "Use patch file and full depthai.cmd binary for usb2 mode" ON) -option(DEPTHAI_CMD_PATH "Use local path for depthai.cmd instead of downloading" OFF) -if(DEPTHAI_USB2_PATCH_ONLY_MODE) - option(DEPTHAI_USB2_PATCH_PATH "Use local path for depthai-usb2-patch.patch instead of downloading" OFF) -else() - option(DEPTHAI_USB2_CMD_PATH "Use local path for depthai-usb2.cmd instead of downloading" OFF) -endif() - -if(DEPTHAI_USB2_PATCH_ONLY_MODE) - message(STATUS "Compiling ${TARGET_CORE_NAME} resources in PATCH_ONLY mode") -else() - message(STATUS "Compiling ${TARGET_CORE_NAME} depthai and depthai-usb2 resources") -endif() # Set constant set(DEPTHAI_RESOURCES_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/resources") @@ -322,18 +342,25 @@ set(DEPTHAI_RESOURCES_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/resources") # Include configuration include(Depthai/DepthaiDeviceSideConfig) # Depthai device binary commit/version configuration include(Depthai/DepthaiBootloaderConfig) # Depthai bootloader binary commit/version configuration +include(Depthai/DepthaiDeviceKbConfig) # depthai-device-kb fwp commit/version configuration +include(Depthai/DepthaiDeviceRVC4Config) # depthai-device-rvc4 fwp commit/version configuration # Include downloaders include(DepthaiDownloader) # Depthai device binary downloader include(DepthaiBootloaderDownloader) # Depthai bootloader binary downloader +include(DepthaiDeviceKbDownloader) # depthai-device-kb fwp downloader # depthai-shared enforce commit hash match if CI if($ENV{CI}) - set(DEPTHAI_SHARED_COMMIT_HASH_ENFORCE ON) + # TODO(themarpe) - Disable before final merge + # set(DEPTHAI_SHARED_COMMIT_HASH_ENFORCE ON) + set(DEPTHAI_SHARED_COMMIT_HASH_ENFORCE OFF) set(DEPTHAI_BOOTLOADER_SHARED_COMMIT_HASH_ENFORCE ON) endif() +# No user specified paths, download from server +message(STATUS "Downloading Depthai device side binaries from server...") # Then get the Depthai device side binaries (local or download) if(DEPTHAI_CMD_PATH OR DEPTHAI_USB2_CMD_PATH OR DEPTHAI_USB2_PATCH_PATH) @@ -352,28 +379,64 @@ if(DEPTHAI_CMD_PATH OR DEPTHAI_USB2_CMD_PATH OR DEPTHAI_USB2_PATCH_PATH) else() # No user specified paths, download from server message(STATUS "Downloading Depthai device side binaries from server...") +endif() + +if(DEPTHAI_ENABLE_DEVICE_FW) + # Add device FW DepthaiDownload( "${DEPTHAI_SHARED_COMMIT_HASH}" "${DEPTHAI_SHARED_COMMIT_HASH_ENFORCE}" - PATCH_ONLY ${DEPTHAI_USB2_PATCH_ONLY_MODE} + PATCH_ONLY ON "${DEPTHAI_RESOURCES_OUTPUT_DIR}" # Output folder DEPTHAI_RESOURCE_LIST # List of output resources "${DEPTHAI_DEVICE_SIDE_MATURITY}" # Maturity "${DEPTHAI_DEVICE_SIDE_COMMIT}" # commit hash "${DEPTHAI_DEVICE_SIDE_VERSION}" # Optional version ) + list(APPEND RESOURCE_COMPILED_FILES ${DEPTHAI_RESOURCE_LIST}) endif() -list(APPEND RESOURCE_COMPILED_FILES ${DEPTHAI_RESOURCE_LIST}) -# Add bootloader -DepthaiBootloaderDownload( - "${DEPTHAI_BOOTLOADER_SHARED_COMMIT_HASH}" "${DEPTHAI_BOOTLOADER_SHARED_COMMIT_HASH_ENFORCE}" - "${DEPTHAI_RESOURCES_OUTPUT_DIR}" # Output folder - DEPTHAI_BOOTLOADER_RESOURCE_LIST # List of output resources - "${DEPTHAI_BOOTLOADER_MATURITY}" # Maturity - "${DEPTHAI_BOOTLOADER_VERSION}" # if maturity == snapshot -> hash else version -) -list(APPEND RESOURCE_COMPILED_FILES ${DEPTHAI_BOOTLOADER_RESOURCE_LIST}) +if(DEPTHAI_ENABLE_DEVICE_BOOTLOADER_FW) + # Add bootloader FW + DepthaiBootloaderDownload( + "${DEPTHAI_BOOTLOADER_SHARED_COMMIT_HASH}" "${DEPTHAI_BOOTLOADER_SHARED_COMMIT_HASH_ENFORCE}" + "${DEPTHAI_RESOURCES_OUTPUT_DIR}" # Output folder + DEPTHAI_BOOTLOADER_RESOURCE_LIST # List of output resources + "${DEPTHAI_BOOTLOADER_MATURITY}" # Maturity + "${DEPTHAI_BOOTLOADER_VERSION}" # if maturity == snapshot -> hash else version + ) + list(APPEND RESOURCE_COMPILED_FILES ${DEPTHAI_BOOTLOADER_RESOURCE_LIST}) +endif() + +if(DEPTHAI_ENABLE_DEVICE_RVC3_FW) + # Add device-kb FW + DepthaiDeviceDownloader( + "depthai-device-kb" + "luxonis-keembay-snapshot-local" + "luxonis-keembay-release-local" + "${DEPTHAI_SHARED_COMMIT_HASH}" "${DEPTHAI_SHARED_COMMIT_HASH_ENFORCE}" + "${DEPTHAI_RESOURCES_OUTPUT_DIR}" # Output folder + DEPTHAI_DEVICE_KB_RESOURCE_LIST # List of output resources + "${DEPTHAI_DEVICE_KB_MATURITY}" # Maturity + "${DEPTHAI_DEVICE_RVC3_VERSION}" + ) + list(APPEND RESOURCE_COMPILED_FILES ${DEPTHAI_DEVICE_KB_RESOURCE_LIST}) +endif() + +if(DEPTHAI_ENABLE_DEVICE_RVC4_FW) + # Add device-RVC4 FW + DepthaiDeviceDownloader( + "depthai-device-rvc4" + "luxonis-rvc4-snapshot-local" + "luxonis-rvc4-release-local" + "${DEPTHAI_SHARED_COMMIT_HASH}" "${DEPTHAI_SHARED_COMMIT_HASH_ENFORCE}" + "${DEPTHAI_RESOURCES_OUTPUT_DIR}" # Output folder + DEPTHAI_DEVICE_RVC4_RESOURCE_LIST # List of output resources + "${DEPTHAI_DEVICE_RVC4_MATURITY}" # Maturity + "${DEPTHAI_DEVICE_RVC4_VERSION}" + ) + list(APPEND RESOURCE_COMPILED_FILES ${DEPTHAI_DEVICE_RVC4_RESOURCE_LIST}) +endif() message(STATUS "LIST OF RESOURCE COMPILED FILES: ${RESOURCE_COMPILED_FILES}") @@ -398,7 +461,7 @@ if(DEPTHAI_BINARIES_RESOURCE_COMPILE) else() # TODO # Don't add RC and don't resource compile the binaries - + # Install to share/ instead for instance endif() # Add include directories @@ -439,6 +502,7 @@ target_link_libraries(${TARGET_CORE_NAME} PUBLIC nlohmann_json::nlohmann_json libnop + spdlog::spdlog INTERFACE XLinkPublic PRIVATE @@ -447,8 +511,8 @@ target_link_libraries(${TARGET_CORE_NAME} BZip2::bz2 FP16::fp16 archive_static - spdlog::spdlog ZLIB::zlib + httplib::httplib ) # Add compile & CMake definitions @@ -459,13 +523,37 @@ target_compile_definitions(${TARGET_CORE_NAME} DEPTHAI_DEVICE_VERSION="${DEPTHAI_DEVICE_VERSION}" # Add depthai-bootloader version DEPTHAI_BOOTLOADER_VERSION="${DEPTHAI_BOOTLOADER_VERSION}" + # Add depthai-device-kb version + DEPTHAI_DEVICE_RVC3_VERSION="${DEPTHAI_DEVICE_RVC3_VERSION}" + # Add depthai-device-rvc4 version + DEPTHAI_DEVICE_RVC4_VERSION="${DEPTHAI_DEVICE_RVC4_VERSION}" ) # Add compile flag if libusb is available if(DEPTHAI_ENABLE_LIBUSB) target_compile_definitions(${TARGET_CORE_NAME} PRIVATE DEPTHAI_ENABLE_LIBUSB) + target_compile_definitions(${TARGET_CORE_NAME} PRIVATE DEPTHAI_HAVE_LIBUSB_SUPPORT) set(DEPTHAI_HAVE_LIBUSB_SUPPORT ON) endif() +if(DEPTHAI_XTENSOR_SUPPORT) + target_compile_definitions(${TARGET_CORE_NAME} PUBLIC DEPTHAI_XTENSOR_SUPPORT) + target_link_libraries(${TARGET_CORE_NAME} PUBLIC xtensor) +endif() + +# Specify available FW +if(DEPTHAI_ENABLE_DEVICE_FW) + target_compile_definitions(${TARGET_CORE_NAME} PRIVATE DEPTHAI_ENABLE_DEVICE_FW) +endif() +if(DEPTHAI_ENABLE_DEVICE_BOOTLOADER_FW) + target_compile_definitions(${TARGET_CORE_NAME} PRIVATE DEPTHAI_ENABLE_DEVICE_BOOTLOADER_FW) +endif() +if(DEPTHAI_ENABLE_DEVICE_RVC3_FW) + target_compile_definitions(${TARGET_CORE_NAME} PRIVATE DEPTHAI_ENABLE_DEVICE_RVC3_FW) +endif() +if(DEPTHAI_ENABLE_DEVICE_RVC4_FW) + target_compile_definitions(${TARGET_CORE_NAME} PRIVATE DEPTHAI_ENABLE_DEVICE_RVC4_FW) +endif() + # Add Backward dependency if enabled (On by default) if(DEPTHAI_ENABLE_BACKWARD) target_compile_definitions(${TARGET_CORE_NAME} PRIVATE DEPTHAI_ENABLE_BACKWARD) @@ -539,7 +627,7 @@ if(DEPTHAI_OPENCV_SUPPORT) # Specify that we are building target opencv target_compile_definitions(${TARGET_OPENCV_NAME} PUBLIC DEPTHAI_TARGET_OPENCV) - + target_compile_definitions(${TARGET_OPENCV_NAME} PUBLIC DEPTHAI_HAVE_OPENCV_SUPPORT) # Add public dependency to depthai::core library target_link_libraries(${TARGET_OPENCV_NAME} PUBLIC ${TARGET_CORE_NAME}) @@ -558,6 +646,76 @@ if(DEPTHAI_OPENCV_SUPPORT) endif() endif() + +######################## +# PCL Support +######################## +set(TARGET_PCL_NAME ${PROJECT_NAME}-pcl) +set(TARGET_PCL_ALIAS pcl) +if(DEPTHAI_PCL_SUPPORT) + if(PCL_FOUND) + # Add depthai-core-pcl library and depthai::core::pcl alias + add_library(${TARGET_PCL_NAME} src/pcl/PointCloudData.cpp) + add_library("${PROJECT_NAME}::${TARGET_PCL_ALIAS}" ALIAS ${TARGET_PCL_NAME}) + # Specifies name of generated IMPORTED target (set to alias) + set_target_properties(${TARGET_PCL_NAME} PROPERTIES EXPORT_NAME ${TARGET_PCL_ALIAS}) + + # Add default flags + add_default_flags(${TARGET_PCL_NAME}) + add_flag(${TARGET_PCL_NAME} -Wno-switch-enum) + + # Link to PCL (publically) + target_link_libraries(${TARGET_PCL_NAME} PUBLIC ${PCL_LIBRARIES}) + + # Add public compile definition indicating that PCL support is available + set(DEPTHAI_HAVE_PCL_SUPPORT ON) + + # Specify that we are building target pcl + target_compile_definitions(${TARGET_PCL_NAME} PUBLIC DEPTHAI_TARGET_PCL) + target_compile_definitions(${TARGET_PCL_NAME} PUBLIC DEPTHAI_HAVE_PCL_SUPPORT) + + + target_include_directories(${TARGET_PCL_NAME} PUBLIC ${PCL_INCLUDE_DIRS}) + target_link_directories(${TARGET_PCL_NAME} PUBLIC ${PCL_LIBRARY_DIRS}) + target_compile_definitions(${TARGET_PCL_NAME} PUBLIC ${PCL_DEFINITIONS}) + + # Add public dependency to depthai::core library + target_include_directories(${TARGET_CORE_NAME} PUBLIC $) + target_link_libraries(${TARGET_PCL_NAME} PUBLIC ${TARGET_CORE_NAME}) + + # Add to clangformat target + if(COMMAND target_clangformat_setup) + target_clangformat_setup(${TARGET_PCL_NAME} "") + endif() + + # Add to list of targets to export and install + list(APPEND targets_to_export ${TARGET_PCL_NAME}) + + message(STATUS "PCL found. PCL Support enabled") + + else() + message(STATUS "PCL not found. PCL Support disabled") + endif() +endif() + +######################## +# Combined target +######################## +set(TARGET_ALL_ALIAS all) +set(TARGET_ALL_NAME ${PROJECT_NAME}-all) +if(DEPTHAI_HAVE_OPENCV_SUPPORT AND DEPTHAI_HAVE_PCL_SUPPORT) + add_library(${TARGET_ALL_NAME} INTERFACE) + add_library("${PROJECT_NAME}::${TARGET_ALL_ALIAS}" ALIAS ${TARGET_ALL_NAME}) + # Specifies name of generated IMPORTED target (set to alias) + set_target_properties(${TARGET_ALL_NAME} PROPERTIES EXPORT_NAME ${TARGET_ALL_ALIAS}) + target_link_libraries(${TARGET_ALL_NAME} INTERFACE ${TARGET_CORE_NAME} ${TARGET_OPENCV_NAME} ${TARGET_PCL_NAME}) + + # Add to list of targets to export and install + list(APPEND targets_to_export ${TARGET_ALL_NAME}) + + message(STATUS "OpenCV and PCL found. Combined target enabled") +endif() + ######################## # Sanitizers ######################## @@ -569,6 +727,9 @@ if(DEPTHAI_SANITIZE) if(DEPTHAI_HAVE_OPENCV_SUPPORT) add_sanitizers(${TARGET_OPENCV_NAME}) endif() + if(DEPTHAI_HAVE_PCL_SUPPORT) + add_sanitizers(${TARGET_PCL_NAME}) + endif() if(DEPTHAI_XLINK_LOCAL) add_sanitizers(XLink) if(XLINK_LIBUSB_LOCAL) @@ -597,6 +758,14 @@ if (DEPTHAI_BUILD_EXAMPLES) add_subdirectory(examples) endif() +if (EMSCRIPTEN) + add_subdirectory(bindings/js) +endif() + +if (DEPTHAI_BUILD_PYTHON) + add_subdirectory(bindings/python) +endif() + ######################## # Documentation ######################## @@ -611,9 +780,8 @@ endif() string(TIMESTAMP BUILD_DATETIME "%Y-%m-%d %H:%M:%S +0000" UTC) message(STATUS "BUILD_DATETIME: ${BUILD_DATETIME}, BUILD_COMMIT: ${BUILD_COMMIT}, BUILD_COMMIT_DATETIME: ${BUILD_COMMIT_DATETIME}") -# Configure build information (version, opencv support) +# Configure build information (version, opencv, pcl support) configure_file("${CMAKE_CURRENT_LIST_DIR}/cmake/version.hpp.in" "${CMAKE_CURRENT_LIST_DIR}/include/depthai/build/version.hpp") -configure_file("${CMAKE_CURRENT_LIST_DIR}/cmake/config.hpp.in" "${CMAKE_CURRENT_LIST_DIR}/include/depthai/build/config.hpp") ######################## # Export and install @@ -669,14 +837,12 @@ if(DEPTHAI_INSTALL) # Install depthai public headers install(DIRECTORY include/ DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") - # Install depthai-shared public headers - install(DIRECTORY "${DEPTHAI_SHARED_PUBLIC_INCLUDE}/" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") - # Install depthai-shared 3rdparty headers - install(DIRECTORY "${DEPTHAI_SHARED_3RDPARTY_INCLUDE}/" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${DEPTHAI_SHARED_3RDPARTY_HEADERS_PATH}") # Install depthai-bootloader-shared public headers install(DIRECTORY "${DEPTHAI_BOOTLOADER_SHARED_PUBLIC_INCLUDE}/" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") # Install Hunter dependencies install(DIRECTORY "${HUNTER_INSTALL_PREFIX}/" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}/dependencies") + # Install depthai-core dependencies + install(DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/3rdparty" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake") # Install resources if not RC'd if(NOT DEPTHAI_BINARIES_RESOURCE_COMPILE) install(DIRECTORY "${DEPTHAI_RESOURCES_OUTPUT_DIR}/" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}") @@ -720,3 +886,11 @@ if(DEPTHAI_HAVE_OPENCV_SUPPORT) $<$:\n-I\'$\'>\n" ) endif() +if(DEPTHAI_HAVE_PCL_SUPPORT) + set(tmp_definitions "$") + set(tmp_includes "$") + file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/depthai-pcl-integration.txt" CONTENT + "$<$:\n-D\'$\'>\n + $<$:\n-I\'$\'>\n" + ) +endif() diff --git a/README.md b/README.md index d951d888f..dea998c7b 100644 --- a/README.md +++ b/README.md @@ -14,13 +14,18 @@ Documentation is available over at [Luxonis DepthAI API](https://docs.luxonis.co DepthAI library doesn't yet provide API stability guarantees. While we take care to properly deprecate old functions, some changes might still be breaking. We expect to provide API stability from version 3.0.0 onwards. ## Dependencies -- CMake >= 3.10 +- CMake >= 3.14 - C/C++14 compiler - [optional] OpenCV 4 (required if building examples) +- [optional] PCL (required for point cloud example) -MacOS: Optional `brew install opencv` +To install OpenCV: +MacOS: `brew install opencv` +Linux: `sudo apt install libopencv-dev` -Linux: Optional `sudo apt install libopencv-dev` +To install PCL: +MacOS: `brew install pcl` +Linux: `sudo apt install libpcl-dev` ## Building @@ -178,7 +183,8 @@ The following environment variables can be set to alter default behavior of the | DEPTHAI_SEARCH_TIMEOUT | Specifies timeout in milliseconds for device searching in blocking functions. | | DEPTHAI_CONNECT_TIMEOUT | Specifies timeout in milliseconds for establishing a connection to a given device. | | DEPTHAI_BOOTUP_TIMEOUT | Specifies timeout in milliseconds for waiting the device to boot after sending the binary. | -| DEPTHAI_PROTOCOL | Restricts default search to the specified protocol. Options: any, usb, tcpip. | +| DEPTHAI_PROTOCOL | Restricts default search to the specified protocol. Options: `any`, `usb`, `tcpip`. | +| DEPTHAI_PLATFORM | Restricts default search to the specified platform. Options: `any`, `rvc2`, `rvc3`, `rvc4`. | | DEPTHAI_DEVICE_MXID_LIST | Restricts default search to the specified MXIDs. Accepts comma separated list of MXIDs. Lists filter results in an "AND" manner and not "OR" | | DEPTHAI_DEVICE_ID_LIST | Alias to MXID list. Lists filter results in an "AND" manner and not "OR" | | DEPTHAI_DEVICE_NAME_LIST | Restricts default search to the specified NAMEs. Accepts comma separated list of NAMEs. Lists filter results in an "AND" manner and not "OR" | diff --git a/bindings/js/.babelrc.js b/bindings/js/.babelrc.js new file mode 100644 index 000000000..9a1ff7975 --- /dev/null +++ b/bindings/js/.babelrc.js @@ -0,0 +1,51 @@ +/** + * Config fragments to be used by all module + * format environments + */ +const sharedPresets = ["@babel/preset-typescript"]; +const sharedIgnoredFiles = ["src/**/*.test.ts"]; +const sharedConfig = { + ignore: sharedIgnoredFiles, + presets: sharedPresets, +}; +/** + * Shared configs for bundles (ESM and UMD) + */ +const bundlePresets = [ + [ + "@babel/preset-env", + { + targets: "> 0.25%, not dead", + }, + ], + ...sharedPresets, +]; +const bundleConfig = { + ...sharedConfig, + presets: bundlePresets, +}; +/** + * Babel Config + */ +module.exports = { + env: { + esmUnbundled: sharedConfig, + esmBundled: bundleConfig, + umdBundled: bundleConfig, + cjs: { + ignore: sharedIgnoredFiles, + presets: [ + [ + "@babel/preset-env", + { + modules: "commonjs", + }, + ], + ...sharedPresets, + ], + }, + test: { + presets: ["@babel/preset-env", ...sharedPresets], + }, + }, +}; diff --git a/bindings/js/.gitignore b/bindings/js/.gitignore new file mode 100644 index 000000000..626c4f31e --- /dev/null +++ b/bindings/js/.gitignore @@ -0,0 +1,2 @@ +/lib +/node_modules diff --git a/bindings/js/CMakeLists.txt b/bindings/js/CMakeLists.txt new file mode 100644 index 000000000..ca177e07f --- /dev/null +++ b/bindings/js/CMakeLists.txt @@ -0,0 +1,28 @@ +set(TARGET_NAME depthai-js) + +add_executable("${TARGET_NAME}" bindings.cpp) + +add_dependencies("${TARGET_NAME}" "${PROJECT_NAME}-core") + +target_link_options( + "${TARGET_NAME}" + PRIVATE + -fwasm-exceptions + --embind-emit-tsd depthai-js.d.ts + -sUSE_ES6_IMPORT_META=0 + -sENVIRONMENT=web + -sMODULARIZE + -sEXPORT_ES6 + -sEXPORT_NAME=depthaiJsModuleInitialize +) +target_link_libraries( + "${TARGET_NAME}" + PRIVATE + "${PROJECT_NAME}-core" + -lembind +) +target_compile_options( + "${TARGET_NAME}" + PUBLIC + -fwasm-exceptions +) diff --git a/bindings/js/README.md b/bindings/js/README.md new file mode 100644 index 000000000..b6b34ccd6 --- /dev/null +++ b/bindings/js/README.md @@ -0,0 +1,32 @@ +# Building +On linux or macos first install the [emscripten sdk](https://emscripten.org/docs/getting_started/downloads.html) to your users home directory `~/emsdk` +So you should have `/home/your_user/emsdk/emsdk_env.sh` file. +And then run: +``` +./bindings/js/configure.sh +./bindings/js/build.sh +``` +on windows or if emscripten sdk is in different location check the above scripts and run the apropriate commands manually. + +The output files are in the root build directory (depthai-core/build): +``` +build/bindings/js/depthai-js.js +build/bindings/js/depthai-js.wasm +build/bindings/js/depthai-js.d.ts +``` + +If something fails delete the build folder or the build folder and the ~/.hunter folder (maybe only the cache folder inside). + +# Usage +Check out the [bindings/js/example folder](example/). + +# Typescript support +There are autogenerated bindings available in `build/bindings/js/depthai-js.d.ts` + +# Future directions +- Maybe add automatic bindings generation using [SWIG's](https://github.com/swig/swig) new wasm and typescript support or using a [custom SWIG language](https://www.swig.org/Doc4.0/Extending.html) to have more freedom / better quality bindings / same swig headers for javascript and python :). New SWIG wasm and typescript support: (https://github.com/mmomtchev/magickwand.js) - (https://mmomtchev.medium.com/effortlessly-porting-a-major-c-library-to-node-js-with-swig-napi-3c1a5c4a233f) . SWIG could then also be used to generate the python bindings in the long run. +- Also support node.js via a native compiled module (better / faster / more functionality (discover packets can be sent...)) or / and WASM module (easier user installation)(is already supported / can be same as the browser one) +- add [npm](https://www.npmjs.com/) support. +- Talk about how to expose all the depthai functions and classes so we don't have memory problems (users don't have to call `obj.delete()` from javascript) and they are nice to use from typescript and javascript. +- Convert from C++ `std::vector` to javascript `Uint8Array` type with zero memory copy using a pointer, the emscripten [HEAP](https://emscripten.org/docs/api_reference/preamble.js.html?highlight=heapu8#type-accessors-for-the-memory-model) and some wrappers. [Example ideas](https://stackoverflow.com/questions/53602955/using-emscripten-how-to-get-c-uint8-t-array-to-js-blob-or-uint8array). But we should first define how we wil be exposing the depthai functions and classes and if we will be using SWIG or not. +- Maybe define a generic `deserialize` function that check the type and returns a custom (depending on C++ class) built `emscripten::val` (this should use code generation to find the C++ types properties...). This would be nice, but we loose embind C++ classes mapping and have to do our own and it wouldn't be nice to use from typescript. diff --git a/bindings/js/bindings.cpp b/bindings/js/bindings.cpp new file mode 100644 index 000000000..f9af95ffc --- /dev/null +++ b/bindings/js/bindings.cpp @@ -0,0 +1,105 @@ +#include +#include + +#include +#include +#include +#include +#include +#include + +// include depthai library +#include +#include +#include + +inline int readIntLE(std::uint8_t* data) { + return data[0] + data[1] * 256 + data[2] * 256 * 256 + data[3] * 256 * 256 * 256; +} + +template +std::shared_ptr daiDeserializeFromJS(std::vector data) { + auto imgFrame = std::make_shared(); + const auto rc = dai::utility::deserialize(data, *imgFrame); + if(!rc) { + // this should never happen as exceptions are enabled !!! + std::cout << "Deserialization failed" << std::endl; + } + return imgFrame; +} + +struct MessageHeader { + dai::DatatypeEnum objectType; + int serializedObjectSize; +}; + +MessageHeader daiGetMessageType(std::vector data) { + if(data.size() < 8) { + throw std::invalid_argument("Message header data should be at least 8 bytes long."); + } + MessageHeader header; + header.serializedObjectSize = readIntLE(data.data() + data.size() - 4); + header.objectType = static_cast(readIntLE(data.data() + data.size() - 8)); + return header; +} + +using namespace emscripten; + +EMSCRIPTEN_BINDINGS(depthai_js) { + // vector types + register_vector("Uint8Vector"); + register_vector("ImgDetectionVector"); + + // enums + enum_("DatatypeEnum") + .value("ADatatype", dai::DatatypeEnum::ADatatype) + .value("Buffer", dai::DatatypeEnum::Buffer) + .value("ImgFrame", dai::DatatypeEnum::ImgFrame) + .value("EncodedFrame", dai::DatatypeEnum::EncodedFrame) + .value("NNData", dai::DatatypeEnum::NNData) + .value("ImageManipConfig", dai::DatatypeEnum::ImageManipConfig) + .value("CameraControl", dai::DatatypeEnum::CameraControl) + .value("ImgDetections", dai::DatatypeEnum::ImgDetections) + .value("SpatialImgDetections", dai::DatatypeEnum::SpatialImgDetections) + .value("SystemInformation", dai::DatatypeEnum::SystemInformation) + .value("SystemInformationS3", dai::DatatypeEnum::SystemInformationS3) + .value("SpatialLocationCalculatorConfig", dai::DatatypeEnum::SpatialLocationCalculatorConfig) + .value("SpatialLocationCalculatorData", dai::DatatypeEnum::SpatialLocationCalculatorData) + .value("EdgeDetectorConfig", dai::DatatypeEnum::EdgeDetectorConfig) + .value("AprilTagConfig", dai::DatatypeEnum::AprilTagConfig) + .value("AprilTags", dai::DatatypeEnum::AprilTags) + .value("Tracklets", dai::DatatypeEnum::Tracklets) + .value("IMUData", dai::DatatypeEnum::IMUData) + .value("StereoDepthConfig", dai::DatatypeEnum::StereoDepthConfig) + .value("FeatureTrackerConfig", dai::DatatypeEnum::FeatureTrackerConfig) + .value("ToFConfig", dai::DatatypeEnum::ToFConfig) + .value("TrackedFeatures", dai::DatatypeEnum::TrackedFeatures) + .value("BenchmarkReport", dai::DatatypeEnum::BenchmarkReport) + .value("MessageGroup", dai::DatatypeEnum::MessageGroup); + + // structs + value_object("MessageHeader") + .field("objectType", &MessageHeader::objectType) + .field("serializedObjectSize", &MessageHeader::serializedObjectSize); + value_object("ImgDetection") + .field("label", &dai::ImgDetection::label) + .field("confidence", &dai::ImgDetection::confidence) + .field("xmin", &dai::ImgDetection::xmin) + .field("xmax", &dai::ImgDetection::xmax) + .field("ymin", &dai::ImgDetection::ymin) + .field("ymax", &dai::ImgDetection::ymax); + + // classes + class_("ImgFrame") + .smart_ptr_constructor("ImgFrame", &std::make_shared) + .property("width", &dai::ImgFrame::getWidth) + .property("height", &dai::ImgFrame::getHeight); + class_("ImgDetections") + .smart_ptr_constructor("ImgDetections", &std::make_shared) + .property("detections", &dai::ImgDetections::detections); + + // module global functions + function("deserializeImgFrame", &daiDeserializeFromJS); + function("deserializeImgDetections", &daiDeserializeFromJS); + function("getMessageType", &daiGetMessageType); +} diff --git a/bindings/js/build.sh b/bindings/js/build.sh new file mode 100755 index 000000000..64a4a09bd --- /dev/null +++ b/bindings/js/build.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +set -e +cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 + +source ~/emsdk/emsdk_env.sh + +cd ../.. + +cmake --build build --target depthai-js --parallel $(($(nproc) * 75 / 100)) +cp build/bindings/js/depthai-js.{d.ts,js} bindings/js/src/ +cd - + +if [ ! -d node_modules ]; then + npm ci +fi + +npm run build diff --git a/bindings/js/configure.sh b/bindings/js/configure.sh new file mode 100755 index 000000000..e83257463 --- /dev/null +++ b/bindings/js/configure.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e +cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 + +source ~/emsdk/emsdk_env.sh + +cd ../.. + +# these additional flags are needed so hunter doesn't fail with: +# [hunter ** FATAL ERROR **] ABI not detected for C compiler +# They shouldn't be needed ... +emcmake cmake -S. -Bbuild -DCMAKE_C_ABI_COMPILED=ON -DCMAKE_CXX_ABI_COMPILED=ON -DCMAKE_CROSSCOMPILING=ON + diff --git a/bindings/js/example/.gitignore b/bindings/js/example/.gitignore new file mode 100644 index 000000000..07e6e472c --- /dev/null +++ b/bindings/js/example/.gitignore @@ -0,0 +1 @@ +/node_modules diff --git a/bindings/js/example/README.md b/bindings/js/example/README.md new file mode 100644 index 000000000..dd39a91d2 --- /dev/null +++ b/bindings/js/example/README.md @@ -0,0 +1,5 @@ +# Usage +First build the depthai javascript bindings to get the `depthai-js.js` and `depthai-js.wasm` file (see the [bindings/js folder](../)). +Then run the example using `./run.sh` and navigate to http://localhost:8000/ in a browser. + +To generate a different `public/img_frame.dump` file you can use `serialize.cpp` from this folder. diff --git a/bindings/js/example/build.sh b/bindings/js/example/build.sh new file mode 100755 index 000000000..624ef001a --- /dev/null +++ b/bindings/js/example/build.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -e +cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 + +source ~/emsdk/emsdk_env.sh + +if [ ! -d node_modules ]; then + npm ci +fi + +npx tsc --noEmit +npx esbuild src/index.ts --bundle --outfile=public/app.js diff --git a/bindings/js/example/package-lock.json b/bindings/js/example/package-lock.json new file mode 100644 index 000000000..610b7ea7f --- /dev/null +++ b/bindings/js/example/package-lock.json @@ -0,0 +1,679 @@ +{ + "name": "depthai-js-example", + "version": "0.0.1", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "depthai-js-example", + "version": "0.0.1", + "license": "MIT", + "dependencies": { + "depthai-js": "file:.." + }, + "devDependencies": { + "esbuild": "0.20.1", + "typescript": "^5.3.3" + } + }, + "..": { + "name": "depthai-js", + "version": "0.0.1", + "license": "MIT", + "devDependencies": { + "@babel/cli": "^7.23.9", + "@babel/core": "^7.24.0", + "@babel/preset-env": "^7.24.0", + "@babel/preset-typescript": "^7.23.3", + "@rollup/plugin-babel": "^6.0.4", + "@rollup/plugin-node-resolve": "^15.2.3", + "cross-env": "^7.0.3", + "npm-run-all": "^4.1.5", + "rimraf": "^5.0.5", + "rollup": "^2.79.1", + "rollup-plugin-terser": "^7.0.2", + "typescript": "^5.3.3" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.1.tgz", + "integrity": "sha512-m55cpeupQ2DbuRGQMMZDzbv9J9PgVelPjlcmM5kxHnrBdBx6REaEd7LamYV7Dm8N7rCyR/XwU6rVP8ploKtIkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.1.tgz", + "integrity": "sha512-4j0+G27/2ZXGWR5okcJi7pQYhmkVgb4D7UKwxcqrjhvp5TKWx3cUjgB1CGj1mfdmJBQ9VnUGgUhign+FPF2Zgw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.1.tgz", + "integrity": "sha512-hCnXNF0HM6AjowP+Zou0ZJMWWa1VkD77BXe959zERgGJBBxB+sV+J9f/rcjeg2c5bsukD/n17RKWXGFCO5dD5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.1.tgz", + "integrity": "sha512-MSfZMBoAsnhpS+2yMFYIQUPs8Z19ajwfuaSZx+tSl09xrHZCjbeXXMsUF/0oq7ojxYEpsSo4c0SfjxOYXRbpaA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.1.tgz", + "integrity": "sha512-Ylk6rzgMD8klUklGPzS414UQLa5NPXZD5tf8JmQU8GQrj6BrFA/Ic9tb2zRe1kOZyCbGl+e8VMbDRazCEBqPvA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.1.tgz", + "integrity": "sha512-pFIfj7U2w5sMp52wTY1XVOdoxw+GDwy9FsK3OFz4BpMAjvZVs0dT1VXs8aQm22nhwoIWUmIRaE+4xow8xfIDZA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.1.tgz", + "integrity": "sha512-UyW1WZvHDuM4xDz0jWun4qtQFauNdXjXOtIy7SYdf7pbxSWWVlqhnR/T2TpX6LX5NI62spt0a3ldIIEkPM6RHw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.1.tgz", + "integrity": "sha512-itPwCw5C+Jh/c624vcDd9kRCCZVpzpQn8dtwoYIt2TJF3S9xJLiRohnnNrKwREvcZYx0n8sCSbvGH349XkcQeg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.1.tgz", + "integrity": "sha512-LojC28v3+IhIbfQ+Vu4Ut5n3wKcgTu6POKIHN9Wpt0HnfgUGlBuyDDQR4jWZUZFyYLiz4RBBBmfU6sNfn6RhLw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.1.tgz", + "integrity": "sha512-cX8WdlF6Cnvw/DO9/X7XLH2J6CkBnz7Twjpk56cshk9sjYVcuh4sXQBy5bmTwzBjNVZze2yaV1vtcJS04LbN8w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.1.tgz", + "integrity": "sha512-4H/sQCy1mnnGkUt/xszaLlYJVTz3W9ep52xEefGtd6yXDQbz/5fZE5dFLUgsPdbUOQANcVUa5iO6g3nyy5BJiw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.1.tgz", + "integrity": "sha512-c0jgtB+sRHCciVXlyjDcWb2FUuzlGVRwGXgI+3WqKOIuoo8AmZAddzeOHeYLtD+dmtHw3B4Xo9wAUdjlfW5yYA==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.1.tgz", + "integrity": "sha512-TgFyCfIxSujyuqdZKDZ3yTwWiGv+KnlOeXXitCQ+trDODJ+ZtGOzLkSWngynP0HZnTsDyBbPy7GWVXWaEl6lhA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.1.tgz", + "integrity": "sha512-b+yuD1IUeL+Y93PmFZDZFIElwbmFfIKLKlYI8M6tRyzE6u7oEP7onGk0vZRh8wfVGC2dZoy0EqX1V8qok4qHaw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.1.tgz", + "integrity": "sha512-wpDlpE0oRKZwX+GfomcALcouqjjV8MIX8DyTrxfyCfXxoKQSDm45CZr9fanJ4F6ckD4yDEPT98SrjvLwIqUCgg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.1.tgz", + "integrity": "sha512-5BepC2Au80EohQ2dBpyTquqGCES7++p7G+7lXe1bAIvMdXm4YYcEfZtQrP4gaoZ96Wv1Ute61CEHFU7h4FMueQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.1.tgz", + "integrity": "sha512-5gRPk7pKuaIB+tmH+yKd2aQTRpqlf1E4f/mC+tawIm/CGJemZcHZpp2ic8oD83nKgUPMEd0fNanrnFljiruuyA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.1.tgz", + "integrity": "sha512-4fL68JdrLV2nVW2AaWZBv3XEm3Ae3NZn/7qy2KGAt3dexAgSVT+Hc97JKSZnqezgMlv9x6KV0ZkZY7UO5cNLCg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.1.tgz", + "integrity": "sha512-GhRuXlvRE+twf2ES+8REbeCb/zeikNqwD3+6S5y5/x+DYbAQUNl0HNBs4RQJqrechS4v4MruEr8ZtAin/hK5iw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.1.tgz", + "integrity": "sha512-ZnWEyCM0G1Ex6JtsygvC3KUUrlDXqOihw8RicRuQAzw+c4f1D66YlPNNV3rkjVW90zXVsHwZYWbJh3v+oQFM9Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.1.tgz", + "integrity": "sha512-QZ6gXue0vVQY2Oon9WyLFCdSuYbXSoxaZrPuJ4c20j6ICedfsDilNPYfHLlMH7vGfU5DQR0czHLmJvH4Nzis/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.1.tgz", + "integrity": "sha512-HzcJa1NcSWTAU0MJIxOho8JftNp9YALui3o+Ny7hCh0v5f90nprly1U3Sj1Ldj/CvKKdvvFsCRvDkpsEMp4DNw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.1.tgz", + "integrity": "sha512-0MBh53o6XtI6ctDnRMeQ+xoCN8kD2qI1rY1KgF/xdWQwoFeKou7puvDfV8/Wv4Ctx2rRpET/gGdz3YlNtNACSA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/depthai-js": { + "resolved": "..", + "link": true + }, + "node_modules/esbuild": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.1.tgz", + "integrity": "sha512-OJwEgrpWm/PCMsLVWXKqvcjme3bHNpOgN7Tb6cQnR5n0TPbQx1/Xrn7rqM+wn17bYeT6MGB5sn1Bh5YiGi70nA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.20.1", + "@esbuild/android-arm": "0.20.1", + "@esbuild/android-arm64": "0.20.1", + "@esbuild/android-x64": "0.20.1", + "@esbuild/darwin-arm64": "0.20.1", + "@esbuild/darwin-x64": "0.20.1", + "@esbuild/freebsd-arm64": "0.20.1", + "@esbuild/freebsd-x64": "0.20.1", + "@esbuild/linux-arm": "0.20.1", + "@esbuild/linux-arm64": "0.20.1", + "@esbuild/linux-ia32": "0.20.1", + "@esbuild/linux-loong64": "0.20.1", + "@esbuild/linux-mips64el": "0.20.1", + "@esbuild/linux-ppc64": "0.20.1", + "@esbuild/linux-riscv64": "0.20.1", + "@esbuild/linux-s390x": "0.20.1", + "@esbuild/linux-x64": "0.20.1", + "@esbuild/netbsd-x64": "0.20.1", + "@esbuild/openbsd-x64": "0.20.1", + "@esbuild/sunos-x64": "0.20.1", + "@esbuild/win32-arm64": "0.20.1", + "@esbuild/win32-ia32": "0.20.1", + "@esbuild/win32-x64": "0.20.1" + } + }, + "node_modules/typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + } + }, + "dependencies": { + "@esbuild/aix-ppc64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.1.tgz", + "integrity": "sha512-m55cpeupQ2DbuRGQMMZDzbv9J9PgVelPjlcmM5kxHnrBdBx6REaEd7LamYV7Dm8N7rCyR/XwU6rVP8ploKtIkA==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.1.tgz", + "integrity": "sha512-4j0+G27/2ZXGWR5okcJi7pQYhmkVgb4D7UKwxcqrjhvp5TKWx3cUjgB1CGj1mfdmJBQ9VnUGgUhign+FPF2Zgw==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.1.tgz", + "integrity": "sha512-hCnXNF0HM6AjowP+Zou0ZJMWWa1VkD77BXe959zERgGJBBxB+sV+J9f/rcjeg2c5bsukD/n17RKWXGFCO5dD5A==", + "dev": true, + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.1.tgz", + "integrity": "sha512-MSfZMBoAsnhpS+2yMFYIQUPs8Z19ajwfuaSZx+tSl09xrHZCjbeXXMsUF/0oq7ojxYEpsSo4c0SfjxOYXRbpaA==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.1.tgz", + "integrity": "sha512-Ylk6rzgMD8klUklGPzS414UQLa5NPXZD5tf8JmQU8GQrj6BrFA/Ic9tb2zRe1kOZyCbGl+e8VMbDRazCEBqPvA==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.1.tgz", + "integrity": "sha512-pFIfj7U2w5sMp52wTY1XVOdoxw+GDwy9FsK3OFz4BpMAjvZVs0dT1VXs8aQm22nhwoIWUmIRaE+4xow8xfIDZA==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.1.tgz", + "integrity": "sha512-UyW1WZvHDuM4xDz0jWun4qtQFauNdXjXOtIy7SYdf7pbxSWWVlqhnR/T2TpX6LX5NI62spt0a3ldIIEkPM6RHw==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.1.tgz", + "integrity": "sha512-itPwCw5C+Jh/c624vcDd9kRCCZVpzpQn8dtwoYIt2TJF3S9xJLiRohnnNrKwREvcZYx0n8sCSbvGH349XkcQeg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.1.tgz", + "integrity": "sha512-LojC28v3+IhIbfQ+Vu4Ut5n3wKcgTu6POKIHN9Wpt0HnfgUGlBuyDDQR4jWZUZFyYLiz4RBBBmfU6sNfn6RhLw==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.1.tgz", + "integrity": "sha512-cX8WdlF6Cnvw/DO9/X7XLH2J6CkBnz7Twjpk56cshk9sjYVcuh4sXQBy5bmTwzBjNVZze2yaV1vtcJS04LbN8w==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.1.tgz", + "integrity": "sha512-4H/sQCy1mnnGkUt/xszaLlYJVTz3W9ep52xEefGtd6yXDQbz/5fZE5dFLUgsPdbUOQANcVUa5iO6g3nyy5BJiw==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.1.tgz", + "integrity": "sha512-c0jgtB+sRHCciVXlyjDcWb2FUuzlGVRwGXgI+3WqKOIuoo8AmZAddzeOHeYLtD+dmtHw3B4Xo9wAUdjlfW5yYA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.1.tgz", + "integrity": "sha512-TgFyCfIxSujyuqdZKDZ3yTwWiGv+KnlOeXXitCQ+trDODJ+ZtGOzLkSWngynP0HZnTsDyBbPy7GWVXWaEl6lhA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.1.tgz", + "integrity": "sha512-b+yuD1IUeL+Y93PmFZDZFIElwbmFfIKLKlYI8M6tRyzE6u7oEP7onGk0vZRh8wfVGC2dZoy0EqX1V8qok4qHaw==", + "dev": true, + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.1.tgz", + "integrity": "sha512-wpDlpE0oRKZwX+GfomcALcouqjjV8MIX8DyTrxfyCfXxoKQSDm45CZr9fanJ4F6ckD4yDEPT98SrjvLwIqUCgg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.1.tgz", + "integrity": "sha512-5BepC2Au80EohQ2dBpyTquqGCES7++p7G+7lXe1bAIvMdXm4YYcEfZtQrP4gaoZ96Wv1Ute61CEHFU7h4FMueQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.1.tgz", + "integrity": "sha512-5gRPk7pKuaIB+tmH+yKd2aQTRpqlf1E4f/mC+tawIm/CGJemZcHZpp2ic8oD83nKgUPMEd0fNanrnFljiruuyA==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.1.tgz", + "integrity": "sha512-4fL68JdrLV2nVW2AaWZBv3XEm3Ae3NZn/7qy2KGAt3dexAgSVT+Hc97JKSZnqezgMlv9x6KV0ZkZY7UO5cNLCg==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.1.tgz", + "integrity": "sha512-GhRuXlvRE+twf2ES+8REbeCb/zeikNqwD3+6S5y5/x+DYbAQUNl0HNBs4RQJqrechS4v4MruEr8ZtAin/hK5iw==", + "dev": true, + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.1.tgz", + "integrity": "sha512-ZnWEyCM0G1Ex6JtsygvC3KUUrlDXqOihw8RicRuQAzw+c4f1D66YlPNNV3rkjVW90zXVsHwZYWbJh3v+oQFM9Q==", + "dev": true, + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.1.tgz", + "integrity": "sha512-QZ6gXue0vVQY2Oon9WyLFCdSuYbXSoxaZrPuJ4c20j6ICedfsDilNPYfHLlMH7vGfU5DQR0czHLmJvH4Nzis/A==", + "dev": true, + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.1.tgz", + "integrity": "sha512-HzcJa1NcSWTAU0MJIxOho8JftNp9YALui3o+Ny7hCh0v5f90nprly1U3Sj1Ldj/CvKKdvvFsCRvDkpsEMp4DNw==", + "dev": true, + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.1.tgz", + "integrity": "sha512-0MBh53o6XtI6ctDnRMeQ+xoCN8kD2qI1rY1KgF/xdWQwoFeKou7puvDfV8/Wv4Ctx2rRpET/gGdz3YlNtNACSA==", + "dev": true, + "optional": true + }, + "depthai-js": { + "version": "file:..", + "requires": { + "@babel/cli": "^7.23.9", + "@babel/core": "^7.24.0", + "@babel/preset-env": "^7.24.0", + "@babel/preset-typescript": "^7.23.3", + "@rollup/plugin-babel": "^6.0.4", + "@rollup/plugin-node-resolve": "^15.2.3", + "cross-env": "^7.0.3", + "npm-run-all": "^4.1.5", + "rimraf": "^5.0.5", + "rollup": "^2.79.1", + "rollup-plugin-terser": "^7.0.2", + "typescript": "^5.3.3" + } + }, + "esbuild": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.1.tgz", + "integrity": "sha512-OJwEgrpWm/PCMsLVWXKqvcjme3bHNpOgN7Tb6cQnR5n0TPbQx1/Xrn7rqM+wn17bYeT6MGB5sn1Bh5YiGi70nA==", + "dev": true, + "requires": { + "@esbuild/aix-ppc64": "0.20.1", + "@esbuild/android-arm": "0.20.1", + "@esbuild/android-arm64": "0.20.1", + "@esbuild/android-x64": "0.20.1", + "@esbuild/darwin-arm64": "0.20.1", + "@esbuild/darwin-x64": "0.20.1", + "@esbuild/freebsd-arm64": "0.20.1", + "@esbuild/freebsd-x64": "0.20.1", + "@esbuild/linux-arm": "0.20.1", + "@esbuild/linux-arm64": "0.20.1", + "@esbuild/linux-ia32": "0.20.1", + "@esbuild/linux-loong64": "0.20.1", + "@esbuild/linux-mips64el": "0.20.1", + "@esbuild/linux-ppc64": "0.20.1", + "@esbuild/linux-riscv64": "0.20.1", + "@esbuild/linux-s390x": "0.20.1", + "@esbuild/linux-x64": "0.20.1", + "@esbuild/netbsd-x64": "0.20.1", + "@esbuild/openbsd-x64": "0.20.1", + "@esbuild/sunos-x64": "0.20.1", + "@esbuild/win32-arm64": "0.20.1", + "@esbuild/win32-ia32": "0.20.1", + "@esbuild/win32-x64": "0.20.1" + } + }, + "typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "dev": true + } + } +} diff --git a/bindings/js/example/package.json b/bindings/js/example/package.json new file mode 100644 index 000000000..e2d5e4d82 --- /dev/null +++ b/bindings/js/example/package.json @@ -0,0 +1,16 @@ +{ + "name": "depthai-js-example", + "version": "0.0.1", + "description": "A simple depthai-js usage example", + "author": "Luxonis ", + "keywords": [], + "license": "MIT", + "scripts": {}, + "devDependencies": { + "esbuild": "0.20.1", + "typescript": "^5.3.3" + }, + "dependencies": { + "depthai-js": "file:.." + } +} diff --git a/bindings/js/example/public/.gitignore b/bindings/js/example/public/.gitignore new file mode 100644 index 000000000..549632dc7 --- /dev/null +++ b/bindings/js/example/public/.gitignore @@ -0,0 +1,2 @@ +/depthai-js.wasm +/app.js diff --git a/bindings/js/example/public/img_frame.dump b/bindings/js/example/public/img_frame.dump new file mode 100644 index 000000000..794a3b7a1 --- /dev/null +++ b/bindings/js/example/public/img_frame.dump @@ -0,0 +1,1615 @@ +ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüù‘Ž‹—‡€È¸±Ìû¿¶®Œ~xpb\ÐÉÄÿÿúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿööô¦¦¤¯¬©¬©¦ª§¤§¤¡¤¡ž¡ž› šš———“““’‘kjhqqq}}}zzzƒƒƒˆˆˆ‡†ˆŠ‰‹‹ŠŒŽ“’”˜—™   ¤¤¤©©©°®¯µ³´º¹·½¼ºÀ¿½ÃÂÀÅÄÂÇÆÄÊÉÇÍÌÊÐÏÍÔÓÑÖÕÓÙØÖÛÚØÝÜÚßÞÜáàÞãâàåäâçæäéèæêéçêéçëêèìëéîëéðíëðíëñîìñîìòïíóðîóðîôñïôñïôñïõòðõòïöóðóóïóóïôôðôôðõôòôóñöóñöóñøõó÷ôò÷ôò÷ôò÷ôò÷ôòöóñöóñöóñõòðõòðõòðõòïöóðôñïôñïôñïõòðóðîôñïóðîòïíóðîòïíòïíóðîòïíóðîòïíðíëòïíïìêðíëðíëðíëðíëïìêïìêïìêíêèíêèîëéíêèíêèìéçëèæìéæëèåêçäìéæìéæëèåìéçíêèèåãêçåéæäéæäéæäèåãèåãèåãçäâèåãèåãéæäæãáæãáèåãæãáåâàæãáäáßæãáåâàáÞÜæãáãàÞâßÝãàÞãàÞãàÞÞÛÙäáßâßÝàÝÛáÞÜáÞÜßÜÙàÝÚâßÜÞÛØÝÚ×ßÜÙáÞÛÞÛØÝÚ×ßÜÙÜÙÖÛØÕÞÛØàÝÚÝÛÕÝÛÕßÝ×ÛÙÓÜÚÔÛÙÓßÛÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüù‘Ž‹–†ɹ²Ìû¼³«Œ~xn`ZÕÎÉÿÿúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôôò¦¦¤°­ª­ª§¨¥¢§¤¡¥¢Ÿ£  šœ™–––’““’‘kjhqqq}}}{{{~~~€€€„„„ˆ‡‰Š‰‹Œ‹‘“’”—–˜œœœ¡¡¡¦¦¦­­­²°±µ³´»º¸¾½»ÂÁ¿ÄÃÁÆÅÃÉÈÆËÊÈÏÎÌÒÑÏÔÓÑÖÕÓÙØÖÜÛÙÝÜÚàßÝâáßäãáåäâçæäèçåéèæêéçëêèíìêïìêðíëñîìñîìñîìòïíôñïôñïôñïôñïôñïõòðõòïõòïóóïôôðôôðôôðôóñôóñöóñöóñ÷ôò÷ôò÷ôò÷ôòöóñöóñöóñöóñöóñõòðõòðõòðöóðõòïõòðõòðôñïõòðõòðôñïóðîóðîôñïóðîòïíòïíòïíòïíóðîñîìðíëðíëðíëðíëðíëïìêïìêïìêíêèíêèîëéíêèíêèíêèìéçìéçìéæëèåëèåìéæëèåëèåëèæëèæêçåêçåèåãéæäêçåéæäéæäèåãçäâéæäæãáèåãæãáæãáçäâæãáæãáåâàåâàåâàäáßãàÞåâàâßÝãàÞäáßäáßâßÝáÞÜâßÝàÝÛâßÝáÞÜâßÝßÜÙáÞÛàÝÚàÝÚàÝÚßÜÙàÝÚÝÚ×ÞÛØßÜÙÝÚ×ÝÚ×ÞÛØßÜÙÜÚÔÜÚÔÝÛÕÞÜÖÛÙÓÛÙÓßÛÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþûøŒ‰•‡€Ê¼µÍļº±©Š|vj\VÙÕÏÿÿúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿòò𥥣®®ªªª¦§§£¦¦¢¦£ ¤¡ž¢Ÿœœ™–––’’’Ž’‘jigrrr{{{{{{‚‚‚†††‡†ˆ‰ˆŠ‹ŠŒŽ“’”˜—™žžž¢¢¢¦¦¦ªªª²°±·µ¶º¹·¿¾¼ÂÁ¿ÆÅÃÈÇÅÌËÉÎÍËÐÏÍÓÒÐÕÔÒ×ÖÔÚÙ×ÝÜÚÞÝÛàßÝâáßäãáåäâçæäèçåéèæêéçëêèìëéíìêîíëñîìòïíòïíòïíôñïôñïôñïóðîôñîõòïõòïöóðóóïóóïóóïôôðôôðôôðôóñóòðöóñ÷ôòöóñ÷ôò÷ôòöóñöóñöóñöóñõòðöóñöóñöóñõòðôñïõòðõòðõòðôñïôñïóðîôñïôñïóðîòïíòïíòïíòïíñîìñîìðíëðíëîíëíìêïìêïìêïìêîëéíêèíêèíêèíêèìéçíêèìéçìéçìéæìéæìéæëèåìéæìéæêçåëèæêçåêçåèåãèåãéæäéæäèåãçäâçäâèåãæãáçäâæãáæãáæãáçäâåâàåâàäáßäáßäáßäáßãàÞãàÞäáßãàÞâßÝáÞÜâßÝáÞÜâßÝáÞÜáÞÜáÞÜßÜÙáÞÛÞÛØãàÝàÝÚÜÙÖáÞÛÞÛØÞÛØßÜÙÝÚ×àÝÚÝÚ×ÝÚ×ÞÜÖÛÙÓÜÚÔÞÜÖÞÜÖÛÙÓàÜÖÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýú÷Š‡–ˆÉ»´Íļº±©‹}wgYSÝÙÓÿÿúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïïí¥¥£®®ª««§¨¨¤¦¦¢¦£ ¤¡ž¡ž›š———“’’Ž‘Žihfwwwzzzxxx€€€ƒƒƒ………ˆ‡‰Š‰‹‹ŠŒŽ”“•˜—™£££¨¨¨ªªª²°±·µ¶»º¸¿¾¼ÂÁ¿ÆÅÃÊÉÇÌËÉÎÍËÑÐÎÕÔÒ×ÖÔØ×ÕÚÙ×ÜÛÙÞÝÛàßÝâáßäãáåäâçæäçæäéèæêéçëêèëêèíìêîíëñîìòïíòïíóðîóðîóðîôñïóðîôñîõòïõòïõòïóóïóóïóóïôôðóóïôôðóòðôóñöóñöóñ÷ôòöóñöóñöóñöóñöóñöóñõòðöóñõòðõòðõòðôñïôñïõòðôñïõòðóðîóðîóðîóðîòïíòïíòïíòïíòïíñîìñîìïìêðíëîíëîíëïìêîëéîëéîëéîëéíêèìéçíêèíêèíêèìéçëèæìéæìéæìéæëèåìéæêçäéæäêçåêçåêçåéæäèåãéæäéæäèåãçäâçäâçäâçäâçäâæãáæãáæãáæãáåâàåâàãàÞåâàãàÞäáßãàÞâßÝâßÝãàÞâßÝâßÝâßÝáÞÜâßÝáÞÜàÝÛáÞÜßÜÙâßÜÞÛØáÞÛÝÚ×ÝÚ×àÝÚßÜÙÝÚ×áÞÛÜÙÖÝÚ×ÞÛØÜÙÖàÞØÙ×ÑÚØÒÝÛÕáßÙØÖÐàÜÖÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúù÷‰ˆ†—‰ƒÉ»µÍź¶®£‰}wfZTåàÝÿÿüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿììꥥ£®®ªªª¦¨¨¤§§£¤¤ ££Ÿ  œšš–——“’’ŽŽhhfvvvyyyxxx~~~ƒ‚„…„†ˆ‡‰‰ˆŠŒŽŽ“’”™˜š¡¡¡¦¦¦«««°°°´´´º¹·¿¾¼ÂÁ¿ÆÅÃÉÈÆÍÌÊÏÎÌÒÑÏÕÔÒ×ÖÔÚÙ×ÛÚØÞÝÛÞÝÛáàÞãâàäãáæåãçæäéèæêéçëêèìëéìëéíìêíìêïîìðïíòïíóðîóðîôñïóðîôñïõòðõòðõòïõòïóóïóóïôôðôôðôôðôôðôóñõôòöóñöóñöóñöóñöóñöóñöóñöóñöóñõòðõòðõòðõòðõòðõòðôñïõòðôñïôñïóðîóðîóðîòïíòïíòïíòïíòïíòïíòïíðíëîíëîíëîíëíìêíìêìëéîëéîëéîëéíêèíêèíêèíêèìéçëèæëèæìéçìéçëèåìéæêçåéæäéæäéæäéæäéæäéæäèåãèåãèåãéæäèåãçäâæãáçäâçäâæãáæãáæãáåâàäáßäáßãàÞåâàäáßäáßâßÝáÞÜãàÞäáßáÞÜãàÞÝÚØãàÞàÝÛáÞÜàÝÚàÝÚáÞÛáÞÛÞÛØßÜÙÜÙÖâßÜáÞÛÝÚ×ÞÛØÝÚ×ÞÛØÜÙÖßÜÙÛØÕÞÜÖÝÛÕÚØÒàÞØÜÚÔØÖÐáÝ×ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷öô†…ƒ™‹…˽·Íź°¨‡{ueYSèãàÿÿüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèè楥£®®ª¬¬¨¨¨¤¦¦¢¤¤ ¢¢žŸŸ›››———“’’ŽŽŽŒffdsss{{{yyyƒ‚„†…‡Š‰‹Š‰‹ŒŽ‘’”“•™˜šžžž¢¢¢§§§¬¬¬°°°µµµ»º¸¿¾¼ÃÂÀÆÅÃÉÈÆÍÌÊÐÏÍÒÑÏÕÔÒØ×ÕÚÙ×ÜÛÙÞÝÛßÞÜàßÝãâàåäâçæäçæäéèæêéçëêèìëéìëéíìêíìêïîìðïíóðîóðîóðîóðîôñïôñïôñïõòðõòïõòïóóïôôðôôðôôðôôðôôðôóñôóñöóñöóñöóñ÷ôòõòðöóñöóñöóñöóñöóñõòðôñïõòðõòðôñïóðîôñïôñïõòðóðîóðîòïíòïíòïíñîìñîìòïíñîìðíëðíëïîìîíëîíëìëéìëéìëéîëéîëéîëéíêèíêèíêèíêèìéçëèæëèæìéçìéçëèåëèåêçåéæäêçåèåãêçåéæäèåãèåãçäâéæäèåãèåãæãáæãáæãáçäâæãáæãáåâàäáßæãáåâàãàÞãàÞäáßäáßáÞÜäáßáÞÜãàÞáÞÜâßÝÞÛÙåâàßÜÚáÞÜàÝÚáÞÛÞÛØàÝÚàÝÚÝÚ×ÝÚ×ãàÝÝÚ×ÞÛØÝÚ×ÛØÕàÝÚÞÛØÝÚ×ÛØÕÛÙÓÞÜÖÛÙÓÛÙÓÚØÒÛÙÓÜØÒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùôñ‡‚šŒ†ÏÁ»ÐÇ¿¬£›ˆ{wcVRäáÞÿÿüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿää⨨¦¯¯«¬¬¨¨¨¤¦¦¢¤¤ ¢¢žŸŸ›››—˜˜”’’ŽŒŒŠggesss|||xxx€€€ƒ‚„…„†‡†ˆ‰ˆŠŒ‹’‘“”“•˜—™œž£¢¤¨¨¨¬¬¬±±±µµµ¹¹·¾¾¼ÃÂÀÇÆÄÊÉÇÎÍËÐÏÍÒÑÏÕÔÒØ×ÕÛÚØÝÜÚÞÝÛßÞÜáàÞãâàäãáçæäçæäèçåêéçëêèëêèìëéíìêíìêïîìðïíñðîñðîñðîñðîñðîòñïòñïóòðóóïóóïóóïõõñôôðôôðõõñôôðôôðôôð÷ôòöóñöóñöóñõòðõòðõòðöóñõòðöóñóòðòñïòñïóòðñðîòñïõòðóðîôñïóðîóðîòïíòïíòïíòïíñîìòïíñîìïîìïîìîíëïîìíìêìëéìëéìëéîëéíêèíêèíêèíêèîëéìéçìéçìéçìéçëèåìéæëèåêçäêçäêçäëèåéæãéæãèåâéæãèåâèåâéæãçäáæãàæãáçäâçäâæãáåâàæãáåâàäáßæãáåâàãàÞãàÞãàÞâßÝãàÞáÞÜãàÞâßÝäáßÝÚØãàÞâßÝâßÝÞÛÙàÝÚáÞÛßÜÙàÝÚÞÛØßÜÙàÝÚàÝÚÝÚ×ÞÛØÜÙÖÞÛØÝÚ×ÝÚ×ÞÛØÜÙÖÜÚÔÝÛÕÛÙÓÜÚÔÜÚÔÚØÒÜÚÔÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøóð…€}›‡ÏÁ»ÐÇ¿ª¡™‰|xdWSéæãÿÿüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿââà©©§®®ª««§§§£§§£¥¥¡££ŸŸŸ›››———“““‹ffdvvv{{{zzz„ƒ……„†‰ˆŠŠ‰‹ŒŽ‘•”–™˜šžŸ£¢¤¦¦¦­­­²²²¶¶¶ºº¸¿¿½ÂÁ¿ÆÅÃÉÈÆÍÌÊÐÏÍÔÓÑÖÕÓØ×ÕÚÙ×ÜÛÙßÞÜàßÝâáßãâàåäâæåãçæäèçåéèæêéçëêèìëéíìêîíëïîìðïíðïíñðîñðîñðîòñïòñïòñïòñïóóïóóïóóïôôðóóïôôðôôðôôðôôðôôðöóñõòðõòðöóñöóñõòðõòðöóñõòðõòðòñïòñïòñïòñïòñïòñïôñïóðîóðîôñïóðîñîìñîìòïíòïíòïíðíëñîìïîìíìêîíëîíëîíëìëéìëéìëéîëéìéçìéçíêèíêèìéçëèæëèæìéçëèæêçäëèåëèåêçäéæãéæãéæãéæãèåâèåâéæãéæãèåâèåâçäáçäáæãáçäâçäâæãáåâàæãáäáßåâàåâàäáßãàÞäáßáÞÜäáßãàÞáÞÜãàÞâßÝâßÝãàÞàÝÛßÜÚâßÝßÜÚáÞÛàÝÚßÜÙáÞÛÝÚ×ÝÚ×ßÜÙâßÜÜÙÖÝÚ×ÞÛØßÜÙÝÚ×ÛØÕßÜÙÛØÕÜÚÔÜÚÔÛÙÓÝÛÕÝÛÕÜÚÔÚØÒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ðí…~{šŽˆË¿¹ÎÇ¿¦Ÿ—ˆ{wdWSîëèÿÿüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÞÜ«ª¨­­©««§©©¥¦¦¢¥¥¡¤¤   œ››———“““ŽŽŒggeyyyzzzzy{~€„ƒ…ƒ‚„‰ˆŠŠ‰‹Œ‹‘–•—š™›žŸ¤£¥§§§¬¬¬°°°¶¶¶ººº¾¾¾ÂÂÀÇÇÅÉÈÆÍÌÊÒÑÏÓÒÐ×ÖÔÙØÖÜÛÙÝÜÚßÞÜáàÞáàÞãâàåäâæåãçæäéèæéèæëêèëêèíìêíìêîíëïîìðïíñðîñðîñðîñðîòòîòòîòòîòòîóóïòòîóóïóóïôôðóóïôôðôôðôôðõõñôôðôôðóòðóòðóòðôóñôóñóòðóòðóòðòñïóòðòñïòñïòñïóòðñðîñðîòñïñðîóðîñîìòïíñîìòïíñîìîíëîíëïîìîíëíìêíìêíìêíìêìëéëêèìëéêéçíêèíêèìéçìéçìéçëèæìéçëèæêçäëèåëèåéæãéæãéæãéæãéæãèåâèåâéæãéæãçäáæãàçäáçäáæãàæãàæãàåâßåâàæãáäáßäáßäáßäáßãàÞãàÞãàÞäáßãàÞáÞÜâßÝáÞÜäáßßÜÚâßÝßÜÚâßÜÞÛØàÝÚáÞÛàÝÚÞÛØáÞÛÝÚ×ßÜÙàÝÚÝÚ×ÞÛØßÜÙÜÙÖÝÚ×ßÜÙÜÙÖÜÙÖÜÚÔßÝ×ØÖÐÛÙÓáßÙÙ×ÑÚØÒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôíêƒ|yœŠË¿¹Íƾ¤•…xteXTòïìÿÿüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜÛÙ«ª¨­­©««§¨¨¤¨¨¤¤¤ ££ŸŸŸ›››———“’’Ž‹ffdyyyzzz{z|~€…„††…‡Š‰‹Š‰‹Œ‹‘–•—›šœžŸ£¢¤¨¨¨¬¬¬²²²¶¶¶»»»¿¿¿ÃÃÁÄÄÂÊÉÇÍÌÊÐÏÍÔÓÑ×ÖÔÙØÖÛÚØÝÜÚßÞÜáàÞáàÞãâàåäâåäâçæäéèæêéçêéçìëéíìêíìêîíëïîìðïíñðîðïíñðîñðîòòîòòîòòîòòîóóïóóïóóïóóïôôðóóïôôðôôðôôðõõñôôðôôðóòðóòðóòðôóñóòðòñïòñïóòðóòðòñïòñïòñïòñïòñïñðîñðîòñïðïíóðîñîìñîìñîìñîìñîìîíëîíëïîìîíëíìêíìêíìêíìêìëéìëéìëéìëéíêèíêèíêèìéçëèæëèæëèæëèæêçäëèåëèåêçäéæãêçäèåâéæãéæãéæãèåâçäáæãàèåâçäáæãàæãàæãàåâßåâßåâàåâàåâàâßÝãàÞãàÞäáßãàÞãàÞãàÞäáßáÞÜâßÝâßÝãàÞßÜÚáÞÜßÜÚâßÜßÜÙßÜÙßÜÙàÝÚßÜÙÝÚ×ÞÛØßÜÙÞÛØÛØÕÞÛØÝÚ×ÝÚ×ÝÚ×ÞÛØÛØÕÛØÕÜÚÔÞÜÖÚØÒÛÙÓÞÜÖØÖÐÙ×Ñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñëê{z‘‹ÍÁ»Íƾ¢›“‡{ui]WôóñÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØÕÓ­ª¨¯¯«¬¬¨¨¨¤§§£¤¤ ££ŸŸŸ›››———“’’Žeeexwyzy{zy{~€…„†‡†ˆŠ‰‹Š‰‹ŒŽ‘’–•—›šœŸž £¢¤¨¨¨¬¬¬²²²···»»»¾¾¾ÂÂÀÆÆÄÊÊÈÌÌÊÑÐÎÔÓÑ×ÖÔØ×ÕÛÚØÝÜÚÞÝÛàßÝáàÞãâàåäâåäâæåãéèæêéçëêèìëéìëéíìêîíëîíëïîìðïíðïíñðîòñïòñïòñïòòîòòîòòîóóïóóïôôðôôðôôðôôðôôðôôðôôðõõñôôðóóïóóïóóïóóïòòîòòîóóïóóïóóïòòîòòîòòîòòîòòîñðîðïíððìððìññíïïëïîìîíëîíëðïíîíëîíëîíëíìêíìêíìêíìêìëéíìêìëéìëéêéçëêèêéçìéçìéçëèæëèæìéæëèåêçäëèåëèåêçäéæãéæãèåâéæãéæãéæãçäáçäáçäáèåâæãàåâßçäáæãàåâßåâßåâßåâßãàÝãàÝãàÝäáÞãàÝâßÜâßÜäáÞäáÞâßÜáÞÛâßÜâßÜàÝÚáÞÛàÝÚáÞÛÞÛØâßÜßÜÙÞÛØáÞÛÞÛØÝÚ×ßÜÙÞÛØÞÛØÜÙÖÞÛØÞÛØÝÚ×ÜÙÖÚØÒÛÙÓÞÜÖÛÙÓÚØÒÝÛÕÚØÒÜÚÔÙ×Ñþþþýýýùùùøøøýýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿòìë€zy ”ŽÍÁ»ÌŽŸ˜ˆ|vj^XöõóÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔÑÏ­ª¨¯¯«¬¬¨©©¥¨¨¤¤¤ ££ŸŸŸ›œœ˜––’““ŒŒŒdddxwy|{}|{}€…„†‡†ˆˆ‡‰‰ˆŠŒŽ‘’–•—œ› Ÿ¡¥¤¦©©©­­­²²²¶¶¶»»»¾¾¾ÃÃÁÇÇÅÉÉÇÌÌÊÑÐÎÔÓÑÖÕÓÙØÖÛÚØÝÜÚÞÝÛàßÝâáßãâàäãáæåãçæäéèæéèæëêèìëéìëéîíëîíëîíëïîìðïíñðîñðîñðîòñïòñïòòîòòîòòîóóïóóïôôðôôðôôðóóïóóïôôðôôðôôðôôðóóïóóïóóïóóïóóïòòîòòîòòîòòîóóïññíññíòòîññíñðîðïíððìññíððìïïëïîìïîìïîìïîìîíëîíëïîìíìêìëéíìêìëéíìêìëéìëéëêèêéçëêèêéçíêèìéçëèæëèæìéæëèåêçäëèåêçäéæãéæãéæãèåâèåâêçäæãàæãàçäáèåâçäáæãàæãàæãàåâßåâßæãàåâßãàÝäáÞåâßãàÝãàÝâßÜãàÝãàÝãàÝáÞÛäáÞàÝÚâßÜãàÝÞÛØâßÜâßÜßÜÙßÜÙâßÜÜÙÖßÜÙßÜÙÞÛØÞÛØÝÚ×ÞÛØßÜÙßÜÙÞÛØÛØÕÜÙÖÛØÕÜÚÔàÞØÛÙÓÚØÒÛÙÓÞÜÖÙ×Ñ×ÕÏÛÙÓùöþóìûêãòêàùóéÿôïúü÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿìéç}zx“É¿¹ÌÆ¿œ–…xtj]Yø÷õÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÑÌɲ­ª®®ª««§ªª¦§§£¥¥¡££Ÿ  œ››—•–’’“‹‹‹ddd{z|{z|zy{€„ƒ……„†‡ˆŠˆ‰‹ŒŽ‘•”–œ› Ÿ¡¤£¥¨¨¨®®®²²²···»»¹¾¾¼ÂÂÀÆÆÄÉÉÇÌÌÊÐÐÎÓÓÑÖÖÔØØÖÜÜÚÜÜÚßÞÜáàÞâáßãâàäãáçæäèçåéèæêéçêéçìëéìëéîíëîíëïîìïîìðïíñðîñðîñðîññíòòîòòîòòîóóïóóïóóïóóïôôðóóïôôðóóïóóïôôðôôðôôðóóïóóïóóïóóïòòîòòîòòîòòîññíòòîññíññíññíððìññíññíððìññíïïëïïëððìïïëîíëïîìíìêîíëîíëíìêìëéíìêìëéìëéìëéìëéëêèêéçêêæëëçêêæééåêçäëèåëèåëèåêçäéæãêçäéæãéæãèåâèåâèåâèåâæãàçäáçäáçäáèåâââÞääàæãàæãàåâßæãàááÝââÞãàÝãàÝäáÞáÞÛààÜââÞãàÝãàÝààÜßßÛààÜààÜßßÛÞÞÚààÜÝÝÙàÝÚáÞÛÝÚ×ÜÙÖàÝÚÞÛØÜÙÖáÞÛàÝÚÞÛØÞÛØÝÚ×ÜÙÖÜÙÖÜÙÖÛØÕÞÜÖÜÚÔÜÚÔÚØÒÛÙÓÛÙÓÜÚÔÚØÒÜÚÔéæîæßîáÚéçÝöôêÿöñü÷òýûûûúúúööö÷÷÷þþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèåã|ywŸ•É¿¹Ëžš”„wsl_[ûúøÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÍÈŲ­ª®®ª¬¬¨©©¥§§£¥¥¡££ŸŸŸ›œœ˜•–’“”‹‹‹eeezy{{z|zy{€…„†…„††‡‰‰ŠŒŠ‹Ž‘–•—›šœ Ÿ¡£¢¤©©©®®®²²²···»»¹¿¿½ÃÃÁÆÆÄÊÊÈÍÍËÐÐÎÓÓÑ××ÕÙÙ×ÛÛÙÜÜÚàßÝáàÞâáßãâàäãáæåãçæäéèæêéçëêèìëéìëéíìêîíëïîìïîìðïíñðîñðîñðîññíññíòòîòòîóóïóóïóóïóóïôôðóóïôôðôôðôôðôôðôôðôôðóóïóóïóóïóóïòòîòòîóóïòòîòòîòòîññíññíññíññíññíññíððìïïëïïëïïëððìîîêîíëîíëíìêíìêîíëìëéìëéìëéìëéëêèëêèëêèëêèëêèêêæêêæêêæééåëèåìéæëèåêçäêçäêçäêçäéæãèåâèåâéæãèåâçäáæãàçäáçäáèåâçäáääàããßæãàåâßåâßåâßááÝááÝãàÝäáÞãàÝãàÝààÜááÝãàÝâßÜßßÛßßÛààÜßßÛÞÞÚááÝÜÜØÝÝÙàÝÚâßÜßÜÙßÜÙßÜÙÞÛØÜÙÖáÞÛßÜÙÛØÕÞÛØáÞÛÜÙÖÝÚ×ÝÚ×ÜÙÖÜÚÔÛÙÓÝÛÕÚØÒÜÚÔÛÙÓÛÙÓÛÙÓÙ×ÑÞÏúàÑüàÑüçÚüòåÿùñþúòÿöðýïéöêàùêàùðêûúôÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿäáß}zx¡—‘ÊÀºËž–‰ƒvrna]üûùÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉÆÄ°­«®®ª««§©©¥§§£¦¦¢££ŸŸŸ›››—•–’“”‰‰‰ddd|{}{z|{z|~€‚ƒ……†ˆ†‡‰ˆ‰‹‹‹“”•—™šœ¡ ¢¥¤¦ªªª®®®²²²···»»»ÁÁÁÃÃÁÆÆÄÉÉÇÍÍËÐÐÎÓÓÑ××ÕØØÖÚÚØÜÜÚÞÞÜààÞâáßãâàäãáæåãçæäéèæéèæëêèëêèíìêîíëîíëïîìïîìððìññíñðîñðîñðîñðîòòîóóïòòîóóïôôðôôðôôðôôðôôðôôðóóïóóïóóïôôðóóïóóïóóïóóïòòîòòîóóïññíññíññíòñïñðîòòîññíññíððìððìïïëïïëïïëïïëîîêîíëíìêíìêîíëîíëíìêíìêëêèíìêìëéëêèëêèëêèëêèêêæêêæêêæèèäééåêêæééåèèäèèäççãéæãèåâææâççãææâååáååáææâååáååáääàååáääàââÞääàââÞââÞââÞààÜââÞââÞââÞááÝßßÛßßÛááÝááÝààÜÞÞÚààÜààÜááÝÞÞÚßßÛßßÛÝÝÙááÝÛÛ×ßßÛÝÝÙÝÝÙÝÝÙÛÛ×ÜÜØÞÛØÞÛØÝÚ×ßÜÙÝÚ×ÝÚ×ÜÙÖÚ×ÔÜÚÔÛÙÓÛÙÓÚØÒÜÚÔÚØÒ×ÕÏÛÙÓ×ÕÏåÖÿêÛÿìÝÿðãÿóæÿòê÷ïçôïéöíçôëáúëáúìæ÷îèùõôöüûýþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÝÚØ|yw¢˜’É¿¹Ëž–‰tpm`\úù÷ÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÇÄ°­«¯¯«¬¬¨ªª¦§§£¥¥¡££ŸŸŸ›››——˜”“”‡‡‡ccc|{}|{}{z|€‚‚ƒ……†ˆ‡ˆŠ‰ŠŒŠŠŽ“•–˜˜™›Ÿž ¥¤¦¨¨¨®®®´´´···»»»ÁÁÁÄÄÂÈÈÆÊÊÈÎÎÌÐÐÎÒÒÐÖÖÔØØÖÛÛÙÜÜÚÞÞÜààÞâáßãâàåäâæåãèçåéèæêéçëêèìëéíìêîíëîíëïîìïîìððìððìñðîðïíñðîòñïòòîóóïòòîóóïóóïôôðóóïôôðóóïóóïóóïóóïóóïóóïóóïóóïôôðóóïòòîòòîòòîññíññíññíñðîñðîññíððìððìððìïïëððìïïëïïëïïëïïëîíëíìêíìêíìêíìêíìêëêèëêèíìêìëéêéçëêèêéçêéçééåêêæèèäèèäêêæééåèèäèèäççãèèäéæãèåâççãççãææâææâååáååáææâååáääàååáääàääàããßááÝááÝââÞââÞááÝááÝââÞááÝááÝÞÞÚààÜààÜààÜßßÛááÝßßÛÝÝÙÞÞÚßßÛÝÝÙßßÛßßÛÝÝÙÞÞÚÝÝÙÞÞÚÝÝÙÛÛ×ÚÚÖÜÙÖàÝÚÝÚ×ÞÛØÝÚ×ÜÙÖÜÙÖÝÚ×Ù×ÑØÖÐÛÙÓÞÜÖÙ×ÑÝÛÕÚØÒÙ×ÑÜÚÔôêÿúñÿýôÿýõÿûóÿ÷íÿëáóèÜüìàÿìâûôêÿüøÿýùÿûøÿòïöîé÷öñÿýûÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØÓÐ~yv¤š”É¿¹Êû•Ž†tpm`\ýúøÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈÂÁ²¬«®®ª««§©©¥§§£¤¤ ££ŸŸŸ›››—•–’”•‘†ˆˆcee|}xy{|{}€‚ƒ…„…‡‡ˆŠ‰ŠŒŒŒ“”•—˜™›Ÿ ¢¢£¥¨¨¨®®®³³³···»»»ÀÀÀÄÄÂÈÈÆÊÊÈÍÍËÑÑÏÓÓÑÖÖÔÙÙ×ÛÛÙÜÜÚÝÝÛßßÝààÞããáååãææäèçåéèæêéçëêèìëéíìêíìêîíëîíëïîìððìððìððìññíñðîñðîòñïóòðóóïóóïóóïóóïóóïóóïôôðóóïóóïôôðóóïóóïóóïóóïóóïòòîòòîòòîññíññíñðîðïíñðîñðîññíððìïïëïïëïïëïïëïïëïïëîíëîíëîíëìëéíìêìëéìëéìëéìëéìëéëêèëêèêéçêéçééåêêæééåééåèèäèèäééåççãççãççãèèäççãççãææâççãææâææâææâääàååáääàääàääàääàääàããßããßââÞááÝââÞââÞßßÛââÞââÞááÝààÜÞÞÚààÜßßÛßßÛààÜßßÛßßÛÞÞÚßßÛÝÝÙÜÜØÜÜØÜÜØÝÝÙßßÛÝÝÙÛÛ×ÛÛ×ÜÜØÛÛ×ÞÞÚÜÜØÙÙÕÛÛ×ÜÙÖÝÚ×ÜÙÖÙÖÓÜÚÔÚØÒÝÛÕÚØÒÚØÒÚØÒÜÚÔÛÙÓÙ×Ñöìÿüóÿýôÿüôÿùñý÷íÿîäöåÙùêÞþñçÿýóÿþúÿÿûÿþûÿüùÿñìúçâðïíñ÷õùûûûýýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÑÌÉ~yv¦œ–ÊÀºÌŽ‘Š‚~qmpc_þûùÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉñ«ª­­©ªª¦©©¥§§£££Ÿ££Ÿ  œšš–”•‘“”„††dff{|~yz||{}€‚ƒ……†ˆ‡ˆŠˆ‰‹‹‹“”•—™šœž £¤¦ªªª¯¯¯´´´¸¸¸½½½ÀÀÀÃÃÁÇÇÅÊÊÈÍÍËÑÑÏÔÔÒÖÖÔØØÖÚÚØÜÜÚÞÞÜßßÝààÞââàääâååãèçåéèæêéçìëéìëéíìêíìêîíëîíëïîìððìññíððìññíñðîñðîòñïòñïòòîòòîóóïóóïóóïóóïóóïóóïóóïóóïóóïóóïóóïóóïòòîóóïòòîòòîòòîññíñðîñðîñðîñðîððìððìððìïïëððìïïëïïëïïëíìêîíëîíëìëéíìêíìêìëéìëéìëéëêèëêèêéçëêèêéçêêæêêæêêæééåééåééåééåèèäççãççãççãèèäççãææâççãææâææâååáååáååáääàääàååáããßããßããßââÞããßââÞââÞááÝßßÛââÞââÞßßÛÞÞÚààÜààÜààÜßßÛââÞÝÝÙÞÞÚààÜááÝÜÜØÝÝÙÝÝÙÜÜØßßÛÜÜØÚÚÖÜÜØÞÞÚÚÚÖÛÛ×ÝÝÙÜÜØÚÚÖÜÜØÝÚ×ÜÙÖÚ×ÔÛØÕÝÛÕÛÙÓÞÜÖÙ×Ñ×ÕÏÝÛÕÚØÒÙ×ÑÛÙÓôèÿùñþùñþùñý÷ïûöíüîåôàÓùçÚÿõíÿþöÿþþþþþþþþþþþþûøÿêçïéÝûïãÿúõþýøÿýýýþþþþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒËÈ€yvª šÊÀºËļ‰rntgcþûùÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÅÂÀ°­«®®ª««§©©¥¨¨¤££Ÿ¢¢žŸŸ›šš–•–’”•‘ƒƒceez{}z{}yz|€ƒ„…‡„…‡‡‡‹‰‰ŒŒ“•–˜š› ¡£¤¥§«««°°°³³³¸¸¸¾¾¾ÁÁÁÄÄÂÇÇÅÊÊÈÎÎÌÒÒÐÔÔÒÖÖÔÙÙ×ÚÚØÜÜÚÞÞÜßßÝááßââàääâææäççåèèæêéçëêèìëéíìêîíëîíëîíëðïíððìððìððìññíññíññíòòîóóïòòîóóïóóïòòîóóïóóïóóïóóïóóïóóïóóïòòîòòîóóïòòîóóïòòîññíññíññíññíññíññíððìððìððìïïëððìïïëïïëïïëîîêîíëîíëìëéíìêíìêìëéìëéìëéìëéëêèììèêêæëëçêêæêêæééåééåééåèèäééåèèäèèäææâèèäççãççãççãççãææâææâææâååáååáååáääàääàååáããßââÞããßââÞââÞââÞââÞààÜááÝààÜààÜááÝààÜààÜßßÛßßÛßßÛààÜÞÞÚÜÜØßßÛßßÛÝÝÙÛÛ×ÜÜØßßÛÝÝÙÜÜØÛÛ×ÝÝÙÚÚÖÞÞÚÛÛ×ÞÞÚÛÛ×ÚÚÖÚÚÖÚÚÖÚÚÖÚÚÖØØÔÙÙÓÛÛÕÞÜÖÖÔÎ×ÕÏÚØÒØÖÐÛÙÓØÖÐíáùóëøüôÿÿ÷ÿÿ÷ÿþõÿòéøáÔúãÖüóëþýõÿýýýþþþþþþþþþýúÿïìôèÜúðäÿûöÿü÷ÿûûûýýýüüüöööúúúþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÐÉÆ€yv¬¢œÊÀºËļ“Œ„tpylhÿüúÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÅÂÀ²¯­®®ª««§©©¥¨¨¤¥¥¡££Ÿ  œœœ˜•–’”•‘cee{|~z{}yz|€‚ƒ„†…†ˆ††Š‰‰‹‹“•–˜š›Ÿ ¢£¤¦ªªª¯¯¯³³³¸¸¸½½½ÁÁÁÄÄÂÇÇÅËËÉÎÎÌÑÑÏÓÓÑÖÖÔÙÙ×ÚÚØÜÜÚßßÝßßÝááßããáååãååãççåééçêéçëêèìëéìëéîíëîíëîíëïîìððìððìððìòòîññíññíòòîóóïóóïóóïòòîòòîóóïóóïóóïôôðóóïóóïóóïòòîòòîóóïòòîòòîòòîññíññíññíññíññíððìððìððìððìððìïïëïïëïïëïïëîîêîíëíìêíìêíìêíìêëêèìëéìëéìëéìëéëëçëëçëëçééåëëçèèäééåèèäééåééåèèäèèäææâèèäææâææâççãççãææâææâææâååáååáääàääàääàääàããßââÞããßââÞââÞââÞââÞááÝààÜààÜááÝààÜààÜÝÝÙááÝààÜßßÛßßÛßßÛßßÛßßÛÛÛ×ßßÛÜÜØßßÛÛÛ×ÜÜØßßÛÞÞÚÚÚÖÚÚÖÝÝÙÜÜØÚÚÖÝÝÙÙÙÕÜÜØÙÙÕÛÛ×ØØÔÙÙÕØØÒÛÛÕÚØÒØÖÐÙ×ÑÜÚÔÚØÒÚØÒÚØÒçÚüìâûüòÿþüþþüþýùÿñíôä×ûãÖúëàüöëÿüúþþüÿþþþþþþüøÿñíôêßûêßûõîýùòÿöñúøóüúõþñìõéß÷öìÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿɽzuª£œÈÁºËļ‰{nj~qmþýûÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁÀ¾°¯­¯¯«««§©©¥§§£¥¥¡££ŸŸ œš›—–—““”€‚‚cee}~€z{}z{}€‚‚ƒ……†ˆˆˆŒŠŠŽŒŒ‘‘••–˜›œžŸ ¢£¤¦ªªª¯¯¯µµµ¸¸¸»»»ÀÀÀÅÅÅÈÈÈËËËÌÌÌÒÒÐÔÔÒ××ÕÙÙ×ÜÜÚÝÝÛÞÞÜààÞááßããáååãååãççåééçééçêêèìëéìëéîíëîíëîíëïîìðïíðïíñðîòñïòòîòòîòòîòòîòòîòòîóóïóóïôôðóóïóóïôôðòòîóóïóóïòòîòòîòòîòòîòòîññíññíòòîòòîññíññíððìððìððìïïëððìïïëïîìîíëîíëîíëîíëîíëíìêíìêíìêëêèìëéìëéììèëëçêêæëëçêêæééåêêæèèäééåèèäèèäèèäêêæççãççãççãææâææâææâææâææâææâååáååáååáããßääàääàääàããßââÞããßââÞââÞââÞááÝááÝááÝààÜááÝààÜßßÛààÜààÜààÜßßÛÝÝÙßßÛßßÛßßÛÛÛ×ààÜÜÜØÜÜØßßÛÝÝÙÜÜØÛÛ×ÝÝÙÙÙÕÞÞÚÙÙÕÛÛ×ÞÞÚ××ÓÝÝÙÚÚÖØØÔÛØÕÝÚ×Ù×ÑÚØÒÙ×ÑÙ×ÑÚØÒÙ×ÑÜÚÔÙ×ÑÖÔÎèÛýçÝöøîÿþüþýûýöòùìèïçÚþéÜÿëàüîãÿöôøûùýýýýûûûôð÷îêñïäÿíâþôíüýöÿü÷ÿùôýøóüñìõèÞöîäüüûýþýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿĽ¸zu«¤ÇÀ¹Ëļ†~{nj„wsÿþüÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ»º¸°¯­®®ªªª¦©©¥¨¨¤¥¥¡££ŸžŸ›š›—•–’•–’~€€cee~{|~{|~€ƒ‚ƒ…„…‡‡‡‹‰‰‹‹”•–˜š›Ÿ ¢¥¦¨«««°°°´´´¹¹¹½½½ÂÂÂÅÅÅÉÉÉËËËÎÎÎÒÒÐÔÔÒÖÖÔÙÙ×ÜÜÚÝÝÛÞÞÜààÞââàääâääâææäèèæééçééçêêèìëéìëéîíëîíëïîìðïíðïíðïíñðîñðîòòîòòîññíòòîóóïóóïòòîóóïôôðóóïóóïóóïóóïòòîôôðòòîóóïóóïòòîòòîññíòòîññíòòîññíððìððìððìïïëîîêððìïïëïîìîíëîíëîíëîíëîíëíìêíìêìëéìëéìëéìëéëëçëëçêêæêêæêêæêêæëëçêêæééåééåééåééåèèäèèäççãèèäææâççãççãççãææâææâååáååáããßããßååáääàããßããßââÞããßááÝââÞââÞààÜààÜààÜßßÛààÜààÜààÜààÜÞÞÚààÜÞÞÚßßÛÞÞÚÝÝÙßßÛÞÞÚÞÞÚÛÛ×ÞÞÚÞÞÚÛÛ×ÜÜØÛÛ×ÞÞÚÚÚÖÞÞÚÚÚÖÚÚÖÙÙÕÚÚÖÜÜØÙÙÕØØÔÞÛØÚ×ÔÙ×ÑÜÚÔÚØÒØÖÐÛÙÓÙ×ÑÚØÒÙ×ÑÖÔÎéÛÿçÚüëÞÿïçúîæùëáùêàøëßýíáÿðãÿïâþíãüîäýñéüòêýòçûòçûöëÿùîÿøðýùñþþøÿþøÿøðýïçôéÝûìàþøòÿÿùÿþþþþþþûùýù÷ûþüÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀ¸³ƒ{v­¦ŸÆ¿¸Éº‰‚zukfˆ~yÿþüÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿµµ³°°®­®ªª«§¨©¥¦§££¤ ¡¢žžŸ››œ˜•–’•–’}dff~{|~{|~‚„ƒ„†…†ˆ‡‡‹ŠŠŽ‘‘‘•––š››ŸŸ ¢¥¦¨©ª¬¯°²´´´¹¹¹¾¾¾ÂÂÂÄÄÄÈÈÈËËËÏÏÏÑÑÏÕÕÓ××ÕÙÙ×ÚÚØÝÝÛÞÞÜààÞââàããáääâææäèèæééçééçêêèëëéììêîíëïîìïîìðïíðïíðïíðïíðïíòñïòñïòòîòòîóóïòòîòòîóóïôôðóóïóóïòòîòòîóóïóóïòòîòòîóóïóóïóóïññíññíòòîòòîññíððìððìððìïïëïïëððìïïëïïëîîêîíëîíëíìêíìêíìêîíëìëéìëéëêèëêèêéçëêèëëçëëçêêæééåêêæééåééåééåééåééåèèäççãççãèèäççãççãççãççãååáææâååáääàããßääàååáããßããßããßââÞááÝááÝááÝããßááÝßßÛááÝßßÛßßÛààÜààÜÞÞÚààÜààÜÝÝÙààÜààÜÜÜØßßÛßßÛÝÝÙÛÛ×ÝÝÙÛÛ×ÝÝÙÛÛ×ÜÜØÛÛ×ÜÜØÛÛ×ÙÙÕÜÜØÚÚÖÛÛ×ÛÛ×××ÓÛÛ×ÙÙÕÙÙÕÙ×ÑÚØÒÝÛÕØÖÐÙ×ÑØÖÐÜÚÔÚØÒ×ÕÏèÚþçÚüëÞÿíåøíåøíãûíãûëßýêÞüëÞúéÜøçÝöåÛôèàóòêýöëÿòçûóèüøíÿûóÿúòÿöð÷øòù÷ïüòê÷íáÿìàþðê÷÷ñþúúúûûûõó÷ëéíðîòúøüýýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸°«‚zu³¬¥Æ¿¸ÇÀ¸‡€xvlg‘‡‚ÿÿýÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþ´´²®®¬­®ª«¬¨¨©¥§¨¤£¤ ¡¢žžŸ›š›—•–’–—“}egg€ƒ|}|}€ƒ„…‡‡ˆŠ‡‡‹‰‰‘’’–——›››Ÿ ¡£¤¥§©ª¬®¯±µµµººº½½½ÁÁÁÆÆÆÈÈÈËËËÎÎÎÒÒÐÕÕÓ××ÕØØÖÜÜÚÝÝÛßßÝààÞââàããáääâææäèèæééçêêèëëéëëéììêîíëïîìîíëïîìðïíðïíðïíñðîòñïòñïòòîòòîòòîòòîòòîòòîóóïóóïòòîóóïóóïòòîóóïòòîòòîòòîóóïòòîññíòòîòòîññíññíððìððìððìððìïïëððìîîêîîêîîêîíëîíëîíëíìêíìêíìêìëéìëéëêèëêèéèæëêèëëçêêæêêæééåêêæèèäééåééåééåèèäççãççãççãèèäççãææâææâææâååáææâååáääàääàääàããßääàääàââÞââÞââÞááÝààÜââÞßßÛßßÛááÝßßÛßßÛßßÛààÜßßÛÞÞÚààÜßßÛÜÜØßßÛÜÜØÜÜØÞÞÚÞÞÚÝÝÙÛÛ×ÛÛ×ÜÜØÝÝÙÜÜØØØÔÞÞÚÙÙÕÚÚÖÙÙÕÙÙÕÜÜØØØÔÙÙÕÚÚÖÚÚÖ××ÓØÖÐÛÙÓÛÙÓÙ×Ñ×ÕÏÛÙÓ×ÕÏÚØÒ×ÕÏïâüçÛûæÚúíáÿðäÿõçÿóåýìÞüêÜúèÜüèÜüêÞþëßÿéÝûîâÿõêþòçûôéýöëÿ÷ïüþöÿúòþóë÷ôæýóåüðãýíàúèÜúèÜúíãûóéÿõëýðæøñåý÷ëÿ÷òý÷òýüùÿþûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ²¨£…{v³¬¥ÇÀ¹ÆÀ¹†€ysjh“Šˆÿÿýÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþ°°®¯¯­­®ªª«§§¨¤¥¦¢£¤ ¡¢žžš™š–••“––”{|~deg€ƒyz||}€ƒ„…‡…†ˆˆˆŒŠŠŽŽŽ’’’–——›¡¡¢¤£¤¦«¬®®¯±µµµººº¾¾¾ÂÂÂÅÅÅÈÈÈËËËÎÎÎÑÑÑÔÔÔ××ÕÚÚØÛÛÙÜÜÚÞÞÜááßââàääâååãççåèèæééçêêèëëéëëéëëéììêííëîíëïîìðïíðïíðïíðïíñðîñðîòñïòñïñðîñðîòñïòñïòñïòñïóóïóóïóóïòòîóóïòòîòòîòòîòòîòòîòñïòñïòñïðïíñðîðïíðïíðïíïîìïîìïîìïîìîíëîíëïîìïîìîíëíìêíìêìëéìëéìëéìëéëêèëêèìëéëêèêéçêéçêéçêéçèçåéèæèçåççãééåééåççãççãèèäççãååáææâååáææâååáããßääàääàããßääàääàääàââÞááÝááÝââÞááÝááÝààÜââÞßßÛààÜÞÞÚßßÛààÜààÜßßÛßßÛÞÞÚÝÝÙÝÝÙÜÜØÝÝÙÞÞÚÝÝÙÜÜØÚÚÖÝÝÙÜÜØÛÛ×ÚÚÖÛÛ×ÚÚÖÚÚÖØØÔÙÙÕÛÛ×ÜÜØÚÚÖÙÙÓÚÚÔÚÚÔÖÖÐØÖÐÚØÒÛÙÓØÖÐØÖÐÚØÒÚØÒÛÙÓÖÔÎöéÿðäÿäØøåÙ÷ìàþôæþóåýíßýîàþóçÿõéÿñåÿôèÿñåÿëßýòçûöëÿ÷ìÿúïÿøðýúòÿþöÿúòþóåüîà÷òåÿòåÿêÞüäØöäÚòìâúôêüïå÷îâúôèÿòíøïêõñîõôñøôôôûûûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿª ›…{v³¬¥Å¾·Å¿¸†€yofd‘ˆ†ÿÿýÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýýý®®¬®®¬¬­©©ª¦§¨¤¥¦¢£¤ ¡¢žžŸ›š›—––”––”xy{fgi‚„z{}|}€ƒ„…‡†‡‰‰‰‹‹ŽŽ’““—––šœœ  ¡£¤¥§ª«­¯°²¶¶¶»»»¾¾¾ÁÁÁÅÅÅÉÉÉËËËÏÏÏÒÒÒÕÕÕ××ÕÚÚØÛÛÙÝÝÛßßÝááßââàããáååãççåèèæééçééçëëéêêèëëéììêííëîíëïîìïîìðïíðïíïîìñðîñðîñðîñðîðïíðïíñðîðïíðïíñðîòòîóóïòòîóóïóóïòòîòòîóóïòòîòòîòñïñðîñðîñðîñðîðïíðïíïîìïîìïîìïîìïîìíìêíìêîíëîíëíìêíìêíìêìëéìëéíìêìëéëêèëêèëêèêéçêéçêéçéèæéèæéèæéèæèçåèèäééåééåççãææâèèäççãææâææâææâææâååáååáååáääàããßããßããßããßââÞââÞááÝââÞààÜßßÛââÞààÜààÜààÜßßÛßßÛÞÞÚßßÛßßÛÝÝÙààÜÜÜØÝÝÙÜÜØÞÞÚÜÜØÝÝÙÜÜØÛÛ×ÜÜØÚÚÖÚÚÖÛÛ×ÛÛ×ÛÛ×ÚÚÖØØÔÚÚÖÝÝÙÖÖÒØØÔÚÚÔØØÒÙÙÓÕÕÏÚØÒÚØÒÙ×Ñ×ÕÏÚØÒØÖÐÙ×Ñ×ÕÏ×ÕÏöéýñåýåÙñÚÊøäÔÿòåÿóæÿñåýõéÿüôÿþöÿöíü÷îýùíÿôèúõêþùîÿüòþýóÿüòþõë÷÷îýùðÿðäüèÜôðãýóæÿñåýîâúæÙûãÖøêÞþçÛûðãýûîÿýöÿöïøñæúöëÿêàùäÚóïèûøñÿþûÿÿüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¨›™‡zx²«¦Ä½¸Ã½¶„~wpge”’ÿÿýÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüüü¯°¬¯°¬¬­©ª«§¨©¥¦§££¤ Ÿ œžš™š–••“••“xy{ghj€ƒz{}{|~€ƒƒƒ‡††ŠˆˆŒŠŠŽ‘““———›››Ÿ ¡£¤¥§ª«­®¯±¶¶¶ººº¾¾¾ÃÃÃÆÆÆÉÉÉËËËÏÏÏÒÒÒÔÔÔ××ÕØØÖÜÜÚÝÝÛààÞááßááßããáååãççåèèæèèæééçêêèëëéëëéííëììêîîìîîìïîìðïíðïíïîìðïíñðîðïíðïíñðîñðîñðîðïíðïíðïíòñïòñïòñïóòðóòðòñïóòðóòðòñïòñïñðîñðîñðîñðîðïíðïíñðîðïíïîìðïíïîìïîìíìêîíëîíëíìêíìêíìêìëéìëéìëéìëéëêèêéçëêèëêèêéçéèæêéçéèæèçåêéçêéçèçåéèæéèæèèäèèäççãææâççãææâååáææâææâååáååáääàããßââÞããßääàããßââÞááÝááÝââÞááÝááÝààÜááÝààÜààÜßßÛßßÛààÜÞÞÚÞÞÚààÜÝÝÙÝÝÙÞÞÚÝÝÙÞÞÚÚÚÖÝÝÙÝÝÙÚÚÖÜÜØÝÝÙÜÜØÙÙÕÙÙÕÜÜØÛÛ×××ÓÜÜØÛÛ×××Ñ××ÑÚÚÖÖÖÒÚØÒÚØÒÚØÒÚØÒØÖÐÛÙÓ×ÕÏÙ×ÑÚØÒÕÓÍÚØÒòåùïãûçÛóÝÍûÞÎüðãýôçÿñåýöêÿüôÿüôÿóêùôëú÷ëýóçùøíÿûðÿýóÿýóÿüòþòèôíäóñè÷ëß÷éÝõòåÿùìÿüðÿüðÿóæÿä×ùäØøã×÷îáûúíÿÿøÿÿøÿôéýñæúéßøäÚóèáôèáôèåìïìóúúúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¦™—†yw´­¨Ã¼·Â¼µ{tnec¨Ÿÿÿýÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüüü¯°¬°±­«¬¨ª«§¨©¥¤¥¡¢£ŸžŸ››œ˜˜™•””’””’vwyhik‚„{|~{|~€ƒ‚‚†……‰ŠŠŽŒŒŽŽ’’’–––š››Ÿ ¡£¤¥§©ª¬®¯±´´´¹¹¹¿¿¿ÂÂÂÅÅÅÉÉÉËËËÏÏÏÒÒÒÔÔÔØØÖÙÙ×ÛÛÙÜÜÚÞÞÜááßââàääâååãççåèèæééçêêèêêèììêììêííëííëîîìîîìïîìïîìðïíðïíðïíðïíðïíðïíòñïñðîðïíðïíñðîðïíñðîñðîòñïòñïòñïòñïóòðóòðòñïòñïñðîñðîñðîñðîñðîðïíñðîðïíðïíïîìïîìïîìîíëîíëîíëîíëíìêìëéìëéìëéìëéëêèëêèëêèëêèëêèêéçêéçêéçéèæéèæëêèêéçèçåçæäèçåççãèèäææâççãççãææâååáææâååáååáååáääàããßããßããßääàááÝããßááÝááÝááÝããßßßÛßßÛßßÛßßÛààÜÞÞÚßßÛááÝÛÛ×ááÝÜÜØÞÞÚßßÛÜÜØßßÛÛÛ×ÜÜØÜÜØßßÛÙÙÕÜÜØÜÜØÛÛ×ØØÔÛÛ×ÛÛ×ØØÔØØÔØØÔÜÜØÛÛÕÖÖÐ××Ó××ÓÜÚÔÛÙÓ×ÕÏÚØÒ×ÕÏÛÙÓÖÔÎÙ×ÑÛÙÓÖÔÎÙ×ÑíàÿìÞüêÜúèÙÿáÒùåÖýìÝÿíàüóæÿøîÿôêüêÝùïâþïâþêÝùñäþñäþñæüðåûñåýíáùçÚüëÞÿæÙûëÞÿùîÿûðÿüõþýöÿüôÿëãðæ×þåÖýåØúîáÿøðýýõÿöìþêàòãÖüÞÑ÷çÚÿêÝÿêÞüçÛùèßøõìÿþüÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŸ™˜yx´°ªÁ½·Á»´ƒ}vlca±¨¦ÿÿýÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûûû®­«±°®¬­©ª«§§¨¤¤¥¡¢£Ÿ ¡›œ˜—˜”””’””’stvklnƒ„†}~€|}‚ƒ…ƒƒ‡‡‡‹‰ŒŠ“““———›¡¡¢¤§¨ª«¬®¯°²µ··¸ºº¾¾¾ÁÁÁÅÅÅÉÉÉÌÌÌÏÏÏÒÒÒÕÕÕØØØÙÙÙÛÛÛÝÝÝààÞááßââàääâååãççåèèæééçêêèëëéììêììêííëííëîîìîîìîîìïïíïïíïïíñðîñðîñðîðïíñðîñðîñðîñðîñðîñðîñðîòñïòñïñðîòñïóòðóòðóòðóòðñðîòñïñðîñðîñðîòñïñðîðïíïîìïîìïîìïîìïîìîíëîíëîíëîíëìëéìëéìëéìëéìëéëêèëêèëêèêéçêéçêéçëêèêéçéèæéèæéèæéèæçæäçæäéèæçæäèçåçæäçæäæåãæåãææâææâååáååáääàääàääàããßããßããßââÞââÞááÝààÜááÝââÞßßÛààÜààÜÞÞÚààÜÞÞÚÞÞÚááÝÝÝÙááÝÜÜØààÜÝÝÙÞÞÚßßÛÜÜØÜÜØÞÞÚÛÛ×ÚÚÖÝÝÙßßÛØØÔÛÛ×ØØÔÝÝÙØØÔÚÚÖÙÙÕÛÛ×ÚÚÖÙÙÕ××ÑÚÚÔÙÙÓÙÙÓØÖÐØÖÐØÖÐÚØÒØÖÐØÖÐÙ×ÑÖÔÎ×ÕÏåØúçÙ÷êÜúêÛÿæ×þÞÏößÐ÷ä×óéÜøìâôçÝïä×óëÞúéÜøàÓïçÚôèÛõèÝóèÝóçÛóâÖîáÔöèÛýãÖøéÜþùîÿûðÿöïøôíöôìùèàíåÖýæ×þä×ùíàÿòê÷ôìùïå÷ãÙëÝÐöÙÌòâÕûîáÿîâÿëßýëâûæÝöìêîù÷ûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿš”“yx²®¨Á½·Àº³„~wkb`¹°®ÿÿýÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùùù«ª¨±°®«¬¨©ª¦§¨¤¤¥¡¢£ŸŸ œœ™—˜”““‘””’stvmnpƒ„†|}|}‚„„„ˆ‡‡‹‰Œ‹Ž‘”’’–˜˜œ  ¤£¤¦¦§©­®°¯°²´¶¶¹»»¿¿¿ÁÁÁÅÅÅÉÉÉÌÌÌÏÏÏÒÒÒÕÕÕØØØÚÚÚÛÛÛÜÜÜààÞààÞââàääâææäççåèèæééçêêèëëéëëéììêììêííëîîìîîìîîìîîìïïíïïíñðîñðîðïíñðîñðîñðîñðîñðîòñïòñïòñïòñïòñïñðîòñïóòðòñïòñïóòðòñïòñïòñïñðîñðîñðîðïíïîìïîìïîìîíëïîìïîìîíëíìêíìêîíëìëéìëéíìêìëéíìêëêèëêèëêèêéçêéçêéçëêèéèæéèæéèæéèæèçåèçåçæäèçåçæäçæäèçåæåãåäâæåãååáææâææâääàääàääàääàããßááÝââÞââÞááÝááÝààÜààÜààÜààÜààÜààÜÞÞÚßßÛÝÝÙÞÞÚßßÛÝÝÙÝÝÙßßÛÞÞÚÜÜØÜÜØÚÚÖÙÙÕßßÛÜÜØÙÙÕØØÔÝÝÙÜÜØØØÔÙÙÕÛÛ×ÚÚÖÚÚÖÛÛ×ÙÙÕ××ÓÚÚÖ××ÓÚÚÔ××ÑÔÔÎØØÒØÖÐ×ÕÏÛÙÓØÖÐÖÔÎÚØÒ×ÕÏÖÔÎÙ×Ñè×ÿïáÿñãÿïâþéÜøÝÍûÖÆôÖÃú×ÄûÙÇúÚÈûßÏýåÕÿàÑýÓÄð×ÅúáÏÿåÖþåÖþàÑýØÉõÖÄùàÎÿÞÎüÜÌúîàþöèÿöèÿòäûéÙüâÒõãÓþâÒýÜÍùäÕÿîàþòäÿïáÿäÖôáÒþäÕÿáÓûêÜÿõêÿõêÿðãýéÜöáÕ÷êÞÿüùÿÿüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþ“Ž~{y³¯©Â¾¸¾¸±ƒ}ve^[½¶³ÿÿýÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøøøª§¥²¯­««©¨¨¦¦¦¤¥¥£££¡ŸŸœœš˜˜–’•’”—”qrtlmo‚ƒ…|}€‚‚ƒ…††ŠˆˆŒ‡Š‰Œ“‘”—˜˜œžž¢¡¢¤¦§©«¬®°±³µ··¹»»¿¿¿ÃÃÃÃÃÃÈÈÈËËËÎÎÎÒÒÒÔÔÔ×××ÚÚÚÛÛÛÝÝÝßßßáááããáääâååãççåèèæééçêêèëëéëëéììêííëîîìîîìîîìîîìîîìïïíïïíððîððîñðîñðîòñïñðîñðîòñïóòðóòðóòðòñïñðîðïíòñïòñïñðîòñïòñïòñïñðîðïíðïíðïíðïíðïíðïíïîìïîìïîìïîìïîìíìêíìêîíëíìêìëéìëéíìêìëéìëéëêèëêèëêèéèæêéçêéçêéçêéçéèæéèæéèæèçåéèæèçåçæäçæäèçåçæäæåãæåãæåãæåãåäâäãáäãáãâàãâàãâàãâàâáßâáßââÞßßÛááÝááÝààÜÞÞÚááÝááÝÝÝÙààÜÝÝÙÞÞÚÞÞÚßßÛÝÝÙÜÜØÝÝÙààÜÚÚÖÝÝÙÛÛ×ÚÚÖÝÝÙÚÚÖÚÚÖÞÞÚÚÚÖÞÞÚÙÙÕÚÚÖ××ÓÚÚÖÚÚÖØØÔÛÛÕ××ÑÛÛÕ××Ñ××ÑÕÕÏØØÒØØÒØÖÐÙ×ÑØÖÐ×ÕÏÕÓÍÛÙÓØÖÐÕÓÍ×ÕÏìÛÿòäÿóåÿñäÿìßûÜÌúØÈöÙÆý×ÄûÖÄ÷ØÆùØÈöÙÉ÷ØÉõÖÇóÕÃøÙÇüÜÍõÙÊò×ÈôÙÊöÖÄùÔÂ÷ÛËùØÈöÝÏíäÖôèÚñçÙðâÒõáÑôáÑüáÑüÛÌøÛÌøâÔòçÙ÷çÙ÷ãÕóåÖÿìÝÿêÜÿå×ÿñæüôéÿïâüíàúîâÿöêÿüùÿÿüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþ‘ŽŒ~{yµ±«À¼¶»µ®‚|uc\YÆ¿¼ÿÿýÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿööö«¨¦±®¬¬¬ª¨¨¦§§¥¤¤¢££¡¢¢ œœš˜˜–“–“•˜•noqlmo€ƒ{|~~‚„„„ˆ‡‡‹‡Š‹Ž‘’•“–™™™žž¢£¤¦¨©«¬­¯±²´³µµ¶¸¸···ÁÁÁÄÄÄÈÈÈÊÊÊÏÏÏÓÓÓ××××××ÙÙÙÜÜÜÝÝÝßßßáááããáääâååãççåèèæêêèêêèëëéëëéììêííëîîìîîìïïíîîìîîìïïíððîððîññïñðîñðîòñïòñïóòðóòðóòðòñïòñïòñïòñïñðîñðîñðîñðîòñïòñïñðîñðîñðîñðîðïíïîìðïíïîìïîìïîìïîìîíëîíëíìêîíëíìêìëéíìêíìêìëéëêèëêèëêèëêèêéçêéçêéçêéçêéçêéçéèæêéçéèæçæäèçåéèæèçåçæäæåãçæäçæäæåãæåãåäâæåãåäâãâàäãáãâàâáßâáßãâàâáßßßÛááÝààÜààÜààÜááÝààÜßßÛßßÛààÜÜÜØààÜßßÛßßÛÝÝÙÝÝÙÝÝÙÜÜØÝÝÙÝÝÙÝÝÙÚÚÖÜÜØÜÜØÚÚÖÜÜØÚÚÖÜÜØÛÛ×ØØÔØØÔØØÔÝÝÙÚÚÖÙÙÓÓÓÍÛÛÕ××Ñ××ÑÛÛÕÙÙÓÖÖÐ×ÕÏÖÔÎÜÚÔÖÔÎÖÔÎÙ×ÑÚØÒÔÒÌØÖÐéØÿðãÿòåÿñäÿíàüÚÈûμïÕ¿ÿÖÀÿÔ¿üÕÀýѽýÖÂÿØÄÿØÄÿÚÆÿÚÆÿÙÅþ×ÃüÕÀýлøĮâįìÚÅÿÝËþÞÌÿßÐüàÑýâÑþâÑþäÕýäÕýâÒýàÐûÜÌúÛËùÜÌúÞÎüäÕýéÚÿêÞþéÝýìÞüìÞüèÜüêÞþóéÿýóÿþüÿÿýÿÿÿÿýýýýýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüüü‡†€zy¸²«Â¼µ¹²­€yt`YVÌÅÂÿÿýÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôôôª©§°¯­««©©©§§§¥¥¥£££¡¢¢ žžœšš˜”—”•˜•noqmnp€ƒ{|~€‚‚„ƒ†‰‡Š‰ŒŒ’“–”—š˜›žž¡¤£¤¦§¨ª¬­¯±²´¶·¹¹º¼ÀÀÀÃÃÃÄÄÄÈÈÈÊÊÊÍÍÍÐÐÐÕÕÕØØØÛÛÛÝÝÝÞÞÞßßßáááãããååååååçççèèæêêèêêèëëéììêììêííëîîìîîìïïíïïíïïíððîððîñðîñðîñðîòñïòñïòñïòñïòñïòñïòñïóòðóòðóòðóòðñðîñðîñðîòñïòñïñðîñðîñðîñðîðïíðïíðïíîíëïîìïîìïîìíìêíìêíìêíìêìëéìëéíìêìëéëêèêéçìëéëêèêéçêéçéèæêéçêéçéèæéèæêéçêéçèçåçæäèçåçæäçæäçæäæåãæåãåäâæåãåäâåäâäãáäãáãâàãâàâáßâáßãâàâáßàßÝáàÞáàÞßßÛááÝààÜààÜßßÛààÜÞÞÚßßÛÞÞÚààÜßßÛÜÜØÞÞÚÜÜØÜÜØÝÝÙÞÞÚÜÜØÜÜØÜÜØÞÞÚÙÙÕÜÜØÛÛ×ÙÙÕÝÝÙÙÙÕØØÔÜÜØ××ÓÛÛÕ××ÑØØÒ××ÑÙÙÓÖÖÐØØÒÙÙÓØØÒÚÚÔÕÓÍÕÓÍÚÚÔÕÕÏÖÔÎÜÚÔÖÔÎÖÔÎÕÓÍØÇøáÔðãÖòàÓïÞÑíÑ¿ò¿­àȲòÓ½ýлøϺ÷Ʋò̸øѽøʶñdzîïêİ鿫䷢߱œÙ¬–Ö¢ŒÌ¥Í¹¤áÔÂõßÍÿàÑýäÕÿæÕÿçÖÿìÝÿîßÿéÙÿç×ÿç×ÿäÔÿßÏýàÐþãÔüäÕýåÙùéÝýîàþìÞüåÙùâÖöäÚòíãûðîòõó÷üüüýýýüüüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúúú‡€{z¹³¬Ä¾·¶¯ª€yt`YVÌÅÂÿÿýÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿòòò¨§¥°¯­¬¬ªªª¨§§¥¥¥£¤¤¢¢¢ žžœ››™”—”–™–lmoopr€ƒ|}€‚ƒ„†„‡Š‡ŠŠŒ’“–“–™˜›žž¡¤¤¥§§¨ª¬­¯±²´µ¶¸»¼¾ÁÁÁÄÄÄÆÆÆÉÉÉËËËÎÎÎÐÐÐÒÒÒ×××ÚÚÚÜÜÜÞÞÞàààáááãããäääæææçççèèæééçêêèììêììêììêííëîîìïïíïïíïïíïïíïïíððîñðîñðîòñïòñïòñïòñïòñïóòðóòðóòðóòðóòðóòðóòðòñïñðîñðîñðîñðîðïíðïíñðîñðîðïíïîìïîìíìêîíëïîìîíëíìêîíëîíëìëéìëéíìêíìêíìêêéçëêèìëéëêèëêèêéçêéçêéçéèæéèæéèæêéçéèæçæäèçåèçåçæäçæäæåãæåãæåãäãáåäâåäâãâàãâàäãáãâàãâàãâàâáßãâàáàÞáàÞáàÞâáßÞÞÚààÜÞÞÚááÝßßÛÞÞÚÞÞÚááÝÞÞÚÝÝÙààÜààÜÜÜØÜÜØÞÞÚÝÝÙÛÛ×ÜÜØÜÜØÝÝÙØØÔÛÛ×ÞÞÚÛÛ×ÛÛ×ÚÚÖÙÙÕØØÔØØÔÙÙÕØØÒÖÖÐÚÚÔÙÙÓÛÛÕÔÔÎÚÚÔÖÖÐØØÒÖÖÐ×ÕÏÙ×ÑÔÔÎÙÙÓÕÓÍÚØÒÕÓÍÖÔÎÙ×ѵœì¿§íªð¾¦ì½¥ëº¡ë²™ã°˜ä¸ ì¹ ê»¢ì»£ï¶žê´›å±˜â¬–Ý¥Ö¤ŽÔ¥ÕŸŠÍ£ŽÑ ŒÍ’~¿{¼—ƒÄ¬–ÜÆ°öÒ½úßÊÿçØÿéÚÿöçÿøéÿóåýíß÷îßÿíÞÿæ×þæ×þèÚþæØüåÖýæ×þåÖýæ×þâÓþÜÍøßÐûñâÿøòÿñëøóíúþøÿþþþþþþÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùùù…~{„}z¹²­Áºµ´®§{t^WTËÄÁÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñññ©¨¦°¯­««©ªª¨¨¨¦¦¦¤££¡¢¢ žžœ™™—’•’–™–klnopr€€„||€~~‚ƒƒ‡†‰Œˆ‹ŽŠŒ’“–”—šššžŸŸ£¤¤¨§§««¬®²³µ¶·¹º»½ÀÀÀÄÄÄÆÆÆÊÊÊÍÍÍÐÐÐÒÒÒÔÔÔÖÖÖÙÙÙÛÛÛÞÞÞßßßáááãããäääåååèèèééçêêèêêèëëéììêííëííëîîìïïíïïíïïíððîððîððîððîððîòñïòñïòñïòñïóòðóòðòñïóòðòñïòñïóòðóòðòñïòñïñðîñðîñðîðïíðïíðïíðïíðïíïîìïîìîíëîíëïîìîíëîíëíìêíìêìëéíìêíìêìëéìëéëêèêéçëêèëêèêéçêéçëêèêéçéèæêéçéèæèçåçæäèçåçæäæåãæåãæåãåäâæåãæåãåäâåäâäãáäãáäãáäãáäãáãâàãâàãâàâáßàßÝàßÝààÜááÝÞÞÚààÜááÝááÝÞÞÚÞÞÚßßÛßßÛßßÛÞÞÚÞÞÚÝÝÙÝÝÙÝÝÙÛÛ×ÞÞÚÛÛ×ÛÛ×ÞÞÚÛÛ×ÛÛ×ÞÞÚÚÚÖÜÜØØØÔÙÙÕØØÔÙÙÕØØÔÛÛ×ÛÛÕØØÒ××ÑÚÚÔÖÖÐÔÔÎØØÒÙÙÓÖÖÐØØÒØÖÐÖÔÎ××ÑÔÔÎ×ÕÏ×ÕÏÖÔÎÖÔÎÛÙÓ¤‹Û©‘׬”Ú­•Û³›áµœæ©Ú¦ŽÚ¥Ù¦×©Ú§Û¤ŒØŸ†ÐœƒÍœ†Í˜‚É•Å•Å’}À‘|¿‰u¶ƒo°‚n¯ˆtµ“}î˜Þ¿ªçØÃÿãÔûæ×þñâü÷èÿ÷éÿïáùíÞÿëÜýèÙÿêÛÿéÛÿäÖúàÑøßÐ÷ÚËòÞÏöÝÎùÜÍøåÖÿúëÿÿùÿüöÿõïüøòÿüüüýýýþþþÿÿÿÿÿÿþþþøøø÷÷÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøøøƒ|yƒ|y»´¯Ã¼·²¬¥‚|u]VSÎÇÄÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðð𪩧±°®««©©©§¨¨¦¥¥£££¡¢¢ ŸŸ››™”—””—”klnqrt€€„||€~~‚ƒƒ‡‡Š‡ŠŠ““–”—š››ŸŸŸ£¥¥©¦¦ª§¨ª²³µ¶·¹º»½ÀÀÀÃÃÃÇÇÇÉÉÉÍÍÍÐÐÐÒÒÒÕÕÕ×××ØØØÚÚÚÜÜÜÝÝÝàààâââãããæææçççééçêêèëëéëëéììêííëííëííëîîìïïíððîððîððîññïññïññïòñïòñïòñïòñïòñïòñïòñïóòðòñïòñïóòðóòðñðîòñïòñïòñïñðîðïíðïíïîìðïíïîìïîìïîìîíëîíëíìêîíëîíëíìêíìêìëéìëéìëéëêèìëéëêèêéçêéçêéçéèæëêèéèæéèæêéçéèæèçåèçåèçåèçåçæäçæäçæäåäâæåãåäâæåãäãáäãáäãáãâàåäâãâàãâàãâàâáßâáßàßÝàßÝâáßààÜââÞÞÞÚßßÛààÜßßÛßßÛßßÛÞÞÚÞÞÚÝÝÙÝÝÙÝÝÙááÝÛÛ×ÚÚÖÞÞÚÞÞÚÛÛ×ÛÛ×ÜÜØÛÛ×ÛÛ×ÙÙÕÚÚÖÛÛ×ØØÔØØÔØØÔÚÚÖØØÔÙÙÕ××ÑØØÒ××Ñ××ÑÚÚÔÔÔÎØØÒÙÙÓÖÖÐØØÒÕÓÍØÖÐÔÔÎÔÔÎÖÔÎÙ×ÑÕÓÍ×ÕÏ×ÕÏ–€ÍšƒÓ˜ÑšƒÓ¢‹Û¡ŠÚ™‚Ò•~Î’{Ë’{Ë–Ï“ÌŒxʼnvÁˆuÀŽ{ÆŒyÄ€p¹{k´{k´xh±ug­qc©oa§se«p¶ˆy¿˜†Ï¶¤íÙÆýÞËÿæÔýëÙÿíÞÿèÙúäÕýßÐøàÏýäÓÿæÔýâÐùÛÉúØÆ÷ÕÁúÚÆÿÜÊýáÏÿïãÿýñÿýüþýüþùôýòíööðýüöÿþþþÿÿÿÿÿÿÿÿÿþþþøøøûûûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿööö‚zu…}x¼µ°Â»¶¯¨£‚{vYROÔÍÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïï﨨¦¯¯­¬¬ª©©§§§¥¥¥£¤¤¢££¡ŸŸœœš”—””—”jkmstv‚‚†||€ƒƒƒ‡…ˆ‹ˆ‹Ž‹Ž‘““–•˜›¡ŸŸ£¤¤¨¦¦ª¨©«²³µµ¶¸º»½¿¿¿ÃÃÃÆÆÆÉÉÉÌÌÌÏÏÏÓÓÓÔÔÔØØØØØØÚÚÚÜÜÜÝÝÝßßßáááäääåååçççèèèêêêëëéììêììêííëîîìîîìîîìïïíñðîñðîððîððîòñïòñïòñïòñïòñïòñïóòðóòðóòðóòðòñïòñïóòðòñïòñïòñïòñïòñïñðîðïíïîìðïíïîìîíëîíëîíëíìêíìêîíëíìêìëéìëéíìêíìêìëéëêèëêèìëéëêèêéçêéçêéçéèæêéçéèæèçåéèæéèæèçåéèæéèæçæäçæäèçåçæääãáåäâæåãæåããâàãâàãâàãâàäãáãâàãâàâáßáàÞäãáßÞÜâáßàßÝáàÞáàÞÞÝÛÝÜÚßÞÜàßÝÞÞÚááÝÜÜØÞÞÚÞÞÚÝÝÙÝÝÙÞÞÚÜÜØÜÜØÜÜØÜÜØÞÞÚÛÛ×ÚÚÖÝÝÙØØÔÙÙÕÚÚÖÚÚÖÜÜØØØÔØØÔÛÛ×ÙÙÕ××ÓÙÙÓØØÒ××ÑÙÙÓÔÔÎ××ÑØØÒÛÛÕ×ÕÏÔÒÌÙ×Ñ×ÕÏØÖÐÕÓÍ×ÕÏØÖÐÖÔÎØÖÐÒÐÊŒvÓ|Ì”}Í’{Ë”}ÍxÈ‹tÄŠsÇpÀ‰rŠsÇsÀ„p½ƒp»‡t¿ŠwÂl·td­qaªp`©m]¦k]£i[¡k]£pb¨wh®xi¯m¶{įœÓȵìØÆïÝËôÜÍî×ÈéÕÆî˼äÈ·åпíÞÌõâÐùßÍþØÆ÷ÔÀùÚÆÿÚÈûÞÌÿéÝûûïÿüûýúùûöñúëæïëåòñëøúúúþþþÿÿÿÿÿÿÿÿÿþþþúúúùùùøøøþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôôôwr†~y¼µ°Áºµ­¦¡‚{vWPMÜÕÒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïïï©©§¯¯­¬¬ªªª¨©©§¤¤¢¥¥£¢¢ žžœ››™”—”•˜•ijlwxzƒƒ‡}}~~‚……‰ˆ‹Ž‰Œ‹Ž‘“‘”—–™œœœ   ¤¥¥©©©­¯°²±²´¶·¹º»½ÁÁÁÄÄÄÇÇÇÊÊÊÎÎÎÐÐÐÓÓÓÖÖÖØØØÚÚÚÝÝÝÞÞÞÞÞÞàààâââãããåååçççéééêêêëëéììêììêííëîîìîîìïïíððîðïíñðîððîññïòñïòñïòñïóòðòñïòñïòñïóòðóòðóòðòñïóòðóòðòñïóòðòñïóòðòñïñðîðïíïîìïîìïîìîíëîíëîíëíìêíìêíìêìëéìëéìëéìëéìëéìëéëêèëêèëêèêéçêéçêéçëêèêéçêéçêéçèçåéèæéèæèçåéèæèçåæåãçæäçæäæåãåäâåäâæåãåäâäãáäãáäãáãâàäãáåäâàßÝáàÞáàÞäãáßÞÜáàÞßÞÜâáßàßÝàßÝÞÝÛÞÝÛàßÝÝÝÙßßÛÝÝÙááÝÜÜØßßÛÞÞÚÞÞÚÜÜØßßÛÚÚÖÝÝÙÝÝÙÚÚÖÝÝÙÜÜØÙÙÕÛÛ×ÛÛ×ØØÔÚÚÖÙÙÕØØÔÚÚÖØØÔÛÛ×ØØÒÕÕÏØØÒÕÕÏØØÒØØÒÚÚÔÕÕÏ×ÕÏ×ÕÏÚØÒØÖÐÕÓÍÕÓÍ×ÕÏÙ×Ñ×ÕÏÔÒÌÕÓÍ€oº~n·}m¶n¹…t¿pºzkµo»q½o»q½ƒs¿~nº~nº€p¼wh²n_©j[¤hY¢i[¡gYŸgYŸfXžm_¥rdªpb¨j\¢rdªyk±}oµˆzÀ¢ŽÕ²žå³ä°šá±šä¨‘Û¢×¥Ú´žäȲø×Ãþѽø˶ùлþɵöмýÚÉúîÝÿóëþðèûêßûåÚöæÙûåØúéßøùïÿÿþÿÿþÿÿÿÿÿÿÿþþþýýýõòùõòùþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñññwrˆ€{½¶±Áºµ©¢€ytRMJáÜÙÿÿýÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿííí©©§¯¯­««©©©§¨¨¦¦¦¤¤¤¢¡¡Ÿžžœ››™”—”•˜•gklx|}‚‚†~~‚~„ƒ†‰ˆ‹Ž‰Œ‹“Ž–“–™˜›ž¡¡¡¥¤¤¨©©­®¯±±²´·¸º»¼¾ÀÀÀÄÄÄÇÇÇËËËÎÎÎÐÐÐÕÕÕÖÖÖÙÙÙÛÛÛÜÜÜßßßàààáááâââãããåååçççéééêêêëëéììêííëîîìîîìïïíïïíððîñðîñðîòñïòñïóòðòñïóòðòñïóòðóòðóòðóòðôóñóòðòñïòñïòñïòñïóòðòñïòñïñðîñðîðïíïîìïîìïîìîíëîíëíìêíìêíìêíìêìëéìëéìëéìëéìëéëêèìëéêéçëêèëêèëêèëêèêéçéèæéèæêéçèçåéèæèçåèçåèçåèçåæåãçæäæåãæåãåäâåäâåäâåäâåäâåäâäãáäãáäãáãâàâáßâáßâáßâáßàßÝàßÝáàÞâáßàßÝßÞÜÝÜÚâáßÞÝÛààÜÝÝÙààÜÞÞÚÜÜØßßÛßßÛÞÞÚÙÙÕÝÝÙÜÜØÝÝÙÚÚÖÚÚÖÚÚÖÚÚÖÝÝÙÛÛ×ÙÙÕ××ÓÚÚÖÙÙÕÚÚÖØØÔÙÙÕÕÕÑØØÔÕÕÑÙÙÓ××ÑÙÙÓ××Ñ×ÕÏÙ×ÑÚØÒ×ÕÏØÖÐÙ×ÑÕÓÍÔÒÌØÖÐ×ÕÏØÖÐÖÔÎÓÑËud¯td­td­tc®{jµvg±rc­qa­sc¯rb®p`¬p`¬td°wg³ue±k\¦gX¢fW dUždVœcU›dVœdVœj\¢i[¡bTšcU›fXžn`¦rdªtf¬‡sº”€Ç˜‚Éœ†Íœ…Ï–É’}ǘƒÍš„Ê£Ó²žÙ¯›Ö°›Þ®™Ü¦’Ó«—ØÅ´åÝÌýß×êàØëâ×óèÝùìßÿêÝÿèÞ÷ñçÿýüþÿþÿÿÿÿÿÿÿþþþþþþýúÿüùÿûûûûûûýýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿîîî€xs‰|¾·²Ã¼·¥ž™~wrNIFèãàÿÿýÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëë몪¨¯¯­¬¬ª««©¨¨¦¥¥£¤¤¢¡¡Ÿ›šš˜”—””—”fjky}~ƒƒ‡~~‚€ƒ†„‡Š‡ŠŠŒŽ”Ž–’•˜—š¡¡¡¥¦¦ª¨¨¬­®°²³µ·¸º»¼¾ÀÀÀÄÄÄÈÈÈÌÌÌÏÏÏÐÐÐÔÔÔ×××ÙÙÙÛÛÛÛÛÛÞÞÞàààáááãããäääåååçççèèèéééëëéììêììêîîìîîìïïíððîððîòñïòñïòñïóòðòñïòñïóòðóòðóòðóòðóòðóòðóòðòñïóòðóòðòñïòñïòñïòñïñðîñðîñðîðïíðïíïîìïîìíìêîíëíìêìëéìëéìëéìëéíìêíìêìëéëêèìëéëêèëêèêéçêéçëêèêéçéèæéèæéèæêéçèçåèçåèçåèçåèçåèçåçæäçæäåäâæåãçæäåäâåäâäãáåäâäãáäãáãâàäãáâáßãâàäãááàÞáàÞáàÞáàÞáàÞáàÞáàÞßÞÜàßÝÞÝÛßÞÜÞÞÚßßÛááÝÛÛ×ÚÚÖààÜÝÝÙÜÜØÜÜØÛÛ×ÞÞÚÞÞÚÙÙÕÜÜØÚÚÖÝÝÙØØÔÙÙÕÜÜØÙÙÕÙÙÕÚÚÖÙÙÕÖÖÒ××Ó××ÓÙÙÕÕÕÑÛÛÕ××Ñ××Ñ××ÑØÖÐ×ÕÏÙ×Ñ×ÕÏÚØÒÔÒÌÖÔÎÖÔÎ×ÕÏÙ×ÑÕÓÍÔÒÌÕÓÍpb¤oa£n`¢qd¨re©oa§l^¤g[£dX dX cWŸcWŸeY¡fZ¢cWŸ^Rš^RšaS™bTš_Q—\N”\O“]P”^Q•^Q•`S—dW›cVšdW›dW›gZžm_¥|n´„s¾‡vÁŒyĆs¾„p½…q¾ŠwÂ|ǕΓÌ{ÈŒxÅŒxÅ‘}ÊžŒÕ°žç·¥æʸùáÒþïàÿøíÿøíÿðãýñäþúõÿþùÿþþþþþþþþþþþþüüüüüüýüþ÷öøñëø÷ñþÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿììì€usŒ¼¸²Á½·žš”}ysNIFíèåÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿççç««©¯¯­­­«««©©©§¥¥£¤¤¢  žžžœ››™–™–“–“ijl€ƒ…~~‚€ƒ†…ˆ‹ˆ‹ŽŠŒŽ”‘—’”š˜š žž¢  ¤¥¥©ªª®®¯±³´¶¸¹»»¼¾ÀÀÀÄÄÄÈÈÈËËËÎÎÎÑÑÑÓÓÓ×××ÙÙÙÛÛÛÜÜÜßßßááááááãããåååççççççèèèéééììììììííëííëïïíððîððîððîòñïòñïóòðòñïòñïóòðóòðóòðóòðóòðóòðòñïòñïóòðóòðòñïóòðòñïòñïòñïñðîñðîðïíïîìïîìîíëîíëîíëíìêìëéìëéëêèìëéìëéíìêìëéìëéëêèìëéëêèëêèéèæêéçëêèêéçéèæéèæéèæéèæèçåèçåèçåèçåèçåèçåçæäæåãèçååäâèçååäâåäâäãáäãáäãáäãáãâàãâàâáßäãáãâàâáßàßÝâáßâáßÞÝÛàßÝàßÝßßÛááÝÝÜÚàßÝßÞÜÞÝÛÞÞÚÝÝÙÞÝÛÜÛÙÞÞÚààÜÜÜØÜÜØÞÞÚÜÜØÚÚÖÛÛ×ÜÜØÚÚÖØØÔÝÝÙÚÚÖÜÜØÖÖÒÛÛ×××ÓØØÔØØÔØØÔØØÒÙÙÓÙÙÕØØÔÖÔÎÛÙÓ×ÕÏØÖÐÛÙÓÖÔÎÙ×ÑÕÓÍÖÔÎ×ÕÏÖÔÎØÖÐ×ÕÏÕÓÍÔÒÌi[i[hZœl_£j]¡eWaS™]Q™]Q™^Rš]Q™^RšbVžcWŸ\P˜ZN–XL”]O•_Q—^P–[M“XK\O“]P”[N’[N’`S—_R–`S—_R–aT˜dVœwi¯wf±q`«ta¬wd¯xd±vb¯xe°}jµ„p½„p½‚n»k¸€l¹ƒo¼{Ä‘ÈžŒÍ·¥æÜÍùêÛÿöëÿøíÿíàúáÔîîéô÷òýûûûýýýþþþþþþýýýùùùûúüùøúõïüòìùúùûþýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿééé~sq‚€¼¸²Á½·™•yuoNIFóîëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿää䪪¨°°®­­«««©¨¨¦¦¦¤¤¤¢¡¡Ÿžžœ››™•˜•”—”ijl‚„‚‚†}}‚…†‰Œˆ‹Ž‹Ž‘•‘—“•›—™Ÿœœ ¢¢¦§§«««¯¯°²³´¶¸¹»¼½¿ÂÂÂÄÄÄÉÉÉËËËÏÏÏÒÒÒÕÕÕØØØÚÚÚÜÜÜÞÞÞßßßàààâââãããåååçççèèèéééêêêëëëìììííëííëîîìððîððîññïñðîòñïòñïòñïòñïóòðóòðóòðòñïóòðóòðòñïòñïòñïòñïòñïòñïòñïñðîñðîñðîñðîïîìðïíïîìðïíîíëíìêíìêíìêëêèìëéìëéìëéìëéëêèìëéëêèëêèìëéëêèêéçêéçëêèéèæêéçéèæèçåéèæéèæéèæéèæèçåçæäéèæèçåæåãæåãåäâæåãåäâåäâãâàäãáäãáäãáâáßäãáãâàãâàãâààßÝßÞÜãâààßÝÞÝÛáàÞàßÝááÝÞÞÚÜÛÙàßÝÞÝÛÞÝÛÝÝÙÞÞÚÞÝÛßÞÜÝÝÙÝÝÙÜÜØÝÝÙÚÚÖÜÜØÜÜØÛÛ×ÜÜØÚÚÖÚÚÖÜÜØÚÚÖÚÚÖÕÕÑØØÔØØÔÙÙÕ××ÓÚÚÖ××ÑÖÖÐÙÙÕ××ÓØÖÐØÖÐÙ×ÑÚØÒÙ×Ñ×ÕÏÔÒÌ×ÕÏØÖÐÕÓÍ×ÕÏÙ×ÑÔÒÌÒÐÊÔÒÌ_R‘bU”`S’aU•]Q‘[N[N[N’ZM‘[N’_R–]R–\Q•ZN”VJWJŽVIVIXKXKYLWJŽXKXKWJŽXKXKZM\O‘]P”_R–^Q•aT˜`S—bU™dW›h[Ÿm_¥n`¦l^¤ug­wh±wh±uf¯uf¯xi²zk´|m·~o¹…t¿œ‹Ö¿«ìØÄÿãÔüãÔüÞÏû×ÈôÝÎúìÝÿúôÿý÷ÿýúþüùýû÷þúöýùôýøóüøóüûöÿýúþú÷ûüùÿÿüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿåååzomŽƒ¼¸²Â¾¸•xspKHEóðíÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿààપ¨¯¯­­­«ªª¨©©§¦¦¤¤¤¢¡¡ŸŸŸœœš”––’””ijl‚„‚‚†~~‚„‡…ˆ‹ˆ‹Ž‹Ž‘•‘—“•›—™ŸŸŸ£££§¦¦ªªª®¯°²´µ·¹º¼»¼¾ÂÁÃÅÄÆÈÈÈËËËÎÎÎÒÒÒÕÕÕØØØÚÚÚÜÜÜÞÞÞàààááááááãããåååçççééééééêêêëëëìììííëîîìîîìïïíñðîñðîñðîóòðòñïòñïòñïóòðòñïòñïòñïóòðòñïòñïñðîñðîòñïñðîòñïñðîñðîñðîñðîñðîðïíðïíðïíðïíïîìîíëíìêìëéëêèëêèìëéìëéëêèëêèìëéëêèëêèëêèêéçêéçêéçëêèéèæêéçéèæèçåéèæéèæéèæèçåèçåçæäéèæçæäæåãåäâæåãåäâæåãåäâäãáäãáåäâãâàâáßäãáãâàãâàâáßàßÝâáßâáßàßÝàßÝáàÞßÞÜáàÞÝÜÚÞÝÛàßÝÝÜÚÝÜÚÞÝÛßÞÜßÞÜÝÜÚÜÜØÜÜØÜÜØÝÝÙÞÞÚÞÞÚÛÛ×ÚÚÖÜÜØÛÛ×ÙÙÕÚÚÖ××ÓÚÚÖÙÙÕÙÙÕÙÙÕ××ÓÖÖÒÚÚÖØÕÒØÕÒÚØÒÛÙÓÚØÒØÖÐØÖÐØÖÐØÖÐÖÔÎ×ÕÏÖÔÎÖÔÎ×ÕÏ×ÕÏÕÓÍÔÒÌÕÓÍ×ÕÏbU”ZMŒYL‹WK‹WK‹UHŠVI‹WJŽWJŽWJŽ^Q•]R–VKUISGUHŒUHŒUHŒTG‹UHŒWJŽXKVITG‹UHŒWJŒXKXKYLŽ^Q•[N’[N’[N’\O“`S—aT˜_R–dVœgYŸk]£l^¤m^§o`©qb«qb«rc¬wh±vg±uf°}l·ˆw‰ʷ£äÒÃëÖÇïÑÂîÔÅñÖÇóÝÎúèâïðê÷ôñõðíñëçîéåìíèñïêóòíöûöÿÿüÿùöúéæíñîõýýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿâââxmk…ƒ»·±Â¾¸’ŠvqnIFCòïìÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜÜܪª¨¯¯­­­«ªª¨©©§¦¦¤¤¤¢¡¡ŸŸŸšš˜“••‘‘hik„…‡…~~‚‚…ˆ†‰Œ‰ŒŒ’‘—‘“™”–œ˜š žž¢££§¦¦ª««¯¯°²³´¶¹º¼¼½¿ÂÁÃÇÆÈÉÉÉËËËÐÐÐÒÒÒÖÖÖÙÙÙÚÚÚÜÜÜÞÞÞàààááááááäääåååçççéééêêêëëëëëëìììííëííëîîìïïíñðîðïíñðîóòðòñïòñïòñïòñïòñïòñïòñïñðîòñïñðîñðîòñïòñïòñïòñïñðîòñïñðîñðîñðîðïíïîìðïíðïíîíëîíëîíëíìêìëéëêèëêèìëéëêèëêèìëéëêèëêèëêèêéçêéçêéçêéçêéçéèæèçåéèæéèæéèæèçåèçåèçåéèæèçåæåãæåãæåãåäâåäâåäâæåãåäâãâàåäâäãáãâàåäââáßâáßâáßáàÞâáßáàÞáàÞáàÞâáßÞÝÛáàÞßÞÜÞÝÛßÞÜßÞÜàßÝÞÝÛÛÚØÜÛÙÜÛÙÞÞÚÝÝÙÝÝÙÜÜØßßÛÚÚÖÛÛ×ÛÛ×ÝÝÙØØÔÚÚÖÛÛ×ÜÜØÛÛ×ØØÔ××Ó××ÓÙÙÕ××ÓÙÙÕÙÖÓÚ×ÔØÖÐÜÚÔ×ÕÏ×ÕÏØÖÐÚØÒÙ×ÑÕÓÍØÖÐÖÔÎ×ÕÏÖÔÎ×ÕÏÕÓÍÔÒÌ×ÕÏ×ÕÏŽŠ¡‚z¤nfYO‰SIƒPD„SG‡PF‡QGˆWJŒXKSIŠQGˆSFˆRE‡RE‡PC…QD†RE‡TG‰UHŠTG‰UHŠRE‡RE‡RE‡SFˆWJŒXK]P’YLŽZMXKXKYLŽZM‘ZM‘\O“cVšgZžeXœ_R–eXœm^§qb«n_¨qb«paªpaªvg°|m¶„u»‘‚Ȧ•Ô·¦åDZ÷кÿÛÇÿÛÇÿÝÎúÞÏûä×ùéÜþçÚüßÒôÞÐøÞÐøÞÑõìßÿúöÿÿûÿõðþâÝëçÞ÷üóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßßßulj‡…»·±Â¾¸‰ƒuqkNKH÷ôñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚÚÚ¬¬ª¯¯­¬¬ª««©ªª¨¦¦¤¥¥£¢¢ žžœšš˜•——’’jkm…†ˆ…ƒƒ†‰†‰ŒŠ‹Ž‘Ž–’˜•—™›¡žž¢¢¢¦§§«««¯°±³´µ·¸¹»½¾ÀÂÁÃÅÄÆÊÊÊÌÌÌÐÐÐÓÓÓÕÕÕÙÙÙÚÚÚÝÝÝßßßßßßàààâââäääåååçççéééêêêêêêëëëìììííííííîîìîîìïïíððîñðîòñïòñïòñïóòðóòðòñïóòðòñïòñïòñïòñïòñïòñïòñïòñïòñïñðîòñïñðîðïíðïíðïíðïíïîìïîìîíëîíëîíëîíëíìêìëéìëéìëéìëéìëéëêèëêèìëéêéçêéçêéçêéçêéçêéçéèæéèæéèæéèæèçåéèæçæäèçåçæäçæäæåãæåãæåãæåãåäâåäâåäâåäâãâàäãáãâàäãáãâàãâàãâàãâàâáßâáßáàÞßÞÜàßÝáàÞàßÝßÞÜàßÝÞÝÛÝÜÚáàÞÜÛÙßÞÜÞÝÛÝÜÚßÞÜÝÝÙßßÛÜÜØÜÜØßßÛÝÝÙÛÛ×ØØÔÚÚÖÛÛ×ÙÙÕÛÛ×ÚÚÖÜÜØÙÙÕÖÖÒ××ÓÙÙÕ××ÓØØÔ×ÔÑÛØÕÙ×ÑÛÙÓÖÔÎÖÔÎÜÚÔÙ×ÑÕÓÍÖÔÎÛÙÓ×ÕÏÕÓÍÙ×ÑÖÔÎÕÓÍÕÓÍÖÔÎÕÓÍ{’…}§Œ„®…{µvl¦dX˜WK‹ND…OE†SFˆQD†MC„LBƒPC…PC…QD†OB„OB„QD†TG‰TG‰PC…RE‡TG‰RE‡QD†PC…SFˆXKXKXKVI‹UHŠTG‰VI‹WJŽXK[N’]P”]P”]P”\O“`S—gX¡k\¥l]¦l]¦j[¤m^§paªqb«vg­}n´Ž}¼ŸŽÍ³ãůõÙÅþÞÊÿåÖÿçØÿçÚüíàÿîáÿëÞÿêÜÿéÛÿâÕùàÓ÷èäïøôÿùôÿèãñßÖïéàùþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßßßtki“Šˆ¼¸²Ã¿¹ˆ„~tpjROLú÷ôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÖÖÖ­­«¯¯­­­«««©ªª¨§§¥¥¥£¡¡Ÿžžœšš˜•——Žijl†‡‰ƒƒ‡€€„ƒ†‰‡ŠŠŒ’Ž–’˜•—˜š žž¢££§§§«««¯°±³µ¶¸¸¹»¼½¿ÃÂÄÆÅÇÊÊÊÌÌÌÐÐÐÔÔÔÖÖÖÙÙÙÚÚÚÜÜÜßßßßßßáááãããäääæææçççèèèéééêêêëëëííííííîîîîîìîîìïïíððîñðîòñïòñïóòðòñïòñïòñïòñïòñïòñïóòðòñïòñïòñïòñïñðîòñïñðîñðîñðîðïíñðîðïíðïíïîìïîìïîìîíëíìêîíëíìêìëéìëéìëéíìêëêèëêèëêèëêèëêèêéçêéçêéçêéçéèæéèæéèæéèæèçåéèæèçåçæäçæäçæäçæäæåãæåãæåãçæäæåãäãáåäâåäâäãáäãáãâàãâàâáßãâàãâàáàÞâáßáàÞßÞÜßÞÜßÞÜßÞÜàßÝßÞÜàßÝßÞÜÞÝÛßÞÜßÞÜÞÝÛÝÜÚÞÝÛÝÜÚÝÝÙßßÛÝÝÙÚÚÖÝÝÙÛÛ×ØØÔÛÛ×ÛÛ×ÛÛ×ÙÙÕÚÚÖÙÙÕÙÙÕÛÛ×ÙÙÕÖÖÒ××ÓÚÚÖÔÔÐÛØÕÙÖÓØÖÐÜÚÔ×ÕÏ×ÕÏÜÚÔØÖÐÕÓÍÚØÒÚØÒÔÒÌÔÒÌÚØÒÔÒÌÒÐÊÓÑËÕÓÍÑÏÉwwwzy{€„ƒ‹‹Š’ŽŠ¡ˆ„›tn™^XƒPHƒLDMAMANB‚PD„RE‡QD†PD„RF†QE…OCƒOCƒPD„SG‡THˆTHˆRF†THˆWK‹VI‹TG‰UHŠTG‰UHŠVI‹UHŠXK\O“\O“ZM‘[N’\O“]P”aS™bTšbTšdVœbTšeWhY¢k\¥paªuf¯}n´ˆy¿—†Ë¥”ÙÁ°ïÓÂÿäÕÿêÛÿíÝÿìÜÿíÞÿíÞÿîàþïáÿêÞþèÜüçÚüíàÿìâûäÚóÔÅ÷ÏÀòèßÿûòÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚÚÚnki‹º¸²À¾¸…€}tolVSPüùöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÓÓÓ¯¯­¯¯­¬¬ª««©¨¨¦§§¥¥¥£¡¡Ÿžžœšš˜”––ijlˆ‰‹……ƒ†‰‡ŠŠŒ’Ž–‘—’”š”–œ™›¡  ¤££§§§«««¯±²´µ¶¸¸¹»½¾ÀÂÁÃÆÅÇÊÊÊÍÍÍÒÒÒÓÓÓ×××ÙÙÙÜÜÜÝÝÝÞÞÞàààâââäääåååæææçççèèèêêêëëëììììììíííïïïïïíïïíððîïïíñðîòñïòñïóòðòñïóòðóòðòñïòñïòñïóòðòñïóòðòñïòñïñðîòñïñðîñðîñðîñðîðïíðïíðïíïîìïîìïîìîíëíìêíìêíìêìëéìëéìëéëêèëêèëêèêéçëêèêéçëêèëêèêéçêéçéèæéèæèçåèçåèçåéèæçæäçæäçæäèçåèçåæåãçæäæåãæåãæåãäãáåäâäãáãâàæåããâàãâàãâàäãáãâàáàÞâáßáàÞàßÝàßÝàßÝáàÞàßÝáàÞàßÝßÞÜÞÝÛßÞÜàßÝÛÚØßÞÜßÞÜßÞÜÜÛÙÛÚØÝÝÙÝÝÙÜÜØÙÙÕÚÚÖÞÞÚÙÙÕÚÚÖÙÙÕÙÙÕÚÚÖÜÜØÞÞÚÏÏËÝÚ×ÜÙÖØÕÒÙÖÓÛØÕ×ÔÑÙ×ÑÜÚÔ×ÕÏØÖÐÜÚÔÔÒÌÖÔÎÚØÒÖÔÎÑÏÉÙ×ÑÔÒÌÔÒÌ×ÕÏÔÒÌÓÑËÔÒÌttttsuutvvu}wv~~z‘ƒ–†€«†€«{s®jbWK‹OCƒL@€MAOB„OB„OCƒOCƒNB‚OCƒPD„OCƒOCƒOCƒQE…QE…RF†UI‰SFˆRE‡UHŠTG‰UHŠWJŒVI‹WJŒWJŽWJŽVIXK\O“]P”\N”]O•^P–_Q—]O•\N”bSœfW k\¥paªsdªyj°ƒr·~ߎͰŸÞÊ»ç;êÑÁäÙÉìÞÏðâÓôå×õéÛùèÜüéÝýêÝÿéÜþåÛôÞÔíØÉû;ðÊÁáÝÔôø÷ùÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÓÓÓnki‘ŽŒ»¹³¿½·ƒ~{snk[XUþûøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÍÍͯ¯­°°®­­«««©ªª¨¦¦¤¦¦¤¢¢ žžœ››™–˜˜ŒŽŽhikŠ‹„„ˆ…ƒ†‰ˆ‹ŽŠŒ’•‘—’”š•—šœ¢¡¡¥¤¤¨ªª®­­±°±³µ¶¸¹º¼¾¿ÁÃÂÄÇÆÈÊÊÊÍÍÍÑÑÑÔÔÔ×××ØØØÛÛÛÞÞÞÞÞÞàààâââäääåååæææèèèèèèéééëëëììììììíííîîîïïíððîïïíððîñðîñðîòñïòñïóòðóòðóòðòñïòñïòñïóòðòñïòñïòñïñðîñðîñðîðïíñðîñðîñðîðïíðïíïîìïîìïîìîíëîíëîíëíìêìëéìëéëêèíìêëêèìëéëêèêéçëêèêéçêéçëêèêéçêéçéèæèçåèçåèçåéèæçæäèçåçæäçæäèçåçæäæåãçæäåäâæåãäãáåäâäãáåäâäãáäãáãâàãâàãâàãâàâáßáàÞáàÞáàÞáàÞàßÝàßÝàßÝßÞÜßÞÜàßÝÞÝÛÞÝÛàßÝÝÜÚÜÛÙÞÝÛÞÝÛÞÝÛÚÙ×ÜÛÙÞÞÚÝÝÙÙÙÕÚÚÖÛÛ×ÜÜØÜÜØØØÔ××ÓÚÚÖÜÜØÚÚÖÙÙÕÒÒÎÚ×ÔÛØÕÙÖÓÛØÕ×ÔÑØÕÒÙ×ÑÙ×ÑÖÔÎÜÚÔÔÒÌÖÔÎÙ×ÑÖÔÎÓÑË×ÕÏÖÔÎÓÑËØÖÐÖÔÎÕÓÍÕÓÍÒÐÊrrrppprrrsssuuuuuuxxxzy{€†„‹‰”‡ƒ›{we^‹RKxJ@zH>xJ@{MC~NCOD‚OD‚NCNCLANB‚NB‚PD„RF†SG‡SG‡TG‰TG‰SFˆUHŠWJŒVI‹UHŒVIVIWJŽZM‘\O“ZM‘]P”]O•\N”[M“\N”^P–bTšgX¡iZ£l]¦sd­wh²~o¹Šzֆϥ“ܯ潨ò»¦ðº¦íÁ­ôË·øÓ¿ÿÓÂúÚÉÿáÑÿáÑÿßÏýßÏýáÑÿßÏýξù¿¯êÍÄëôëÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÎÎÎnki•’»¹³¿½·|yqli[ZXýüúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈÈȯ®¬±°®¬¬ªªª¨ªª¨§§¥¥¥£¢¢ žžœ››™—™™ŒŽŽgjmˆ‹Žƒƒ‡…„‡Š‰ŒŒŽ”•‘—“•›–˜žšœ¢  ¤¤¤¨¦¦ª®®²±²´µ¶¸º»½¿ÀÂÄÃÅÈÇÉËËËÎÎÎÒÒÒÔÔÔØØØÙÙÙÛÛÛÞÞÞßßßßßßáááäääæææçççèèèééééééëëëìììíííîìíïíîïïíððîñðîñðîñðîñðîòñïòñïóòðóòðóòðòñïóòðòñïóòðñðîòñïóòðñðîñðîñðîðïíñðîðïíðïíðïíðïíïîìïîìïîìîíëîíëíìêíìêíìêìëéìëéìëéìëéìëéëêèêéçëêèëêèêéçêéçêéçéèæéèæéèæèçåéèæèçåçæäèçåçæäèçåçæäçæäçæäæåãæåãåäâåäâåäâåäâäãáãâàäãáäãáãâàâáßáàÞãâàâáßàßÝâáßáàÞáàÞàßÝàßÝßÞÜÝÜÚàßÝÝÜÚßÞÜÞÝÛÞÝÛÞÝÛÜÛÙÝÜÚÜÛÙÛÚØÝÜÚÝÝÙÚÚÖÛÛ×ÚÚÖÛÛ×ÙÙÕÞÞÚ××ÓÙÙÕÞÞÚÛØÕÚ×ÔØÕÒÚ×ÔÖÓÐÜÙÖÙÖÓØÕÒÙÖÓÙÖÓ×ÔÑÖÓÐ×ÕÏÛÙÓÓÑË×ÕÏÙ×ÑÖÔÎÙ×ÑÕÓÍÕÓÍÕÓÍ×ÕÏÓÑËÖÔÎÒÐÊÓÑËnnnoooooooooqqqrrrtttutvvuwvtzxƒ~z’…™„}ªx¥pf \RŒPFKA|I>|K@~J?}K@~MB€LAK?NB‚OCƒQE…PD„PD„QD†TG‰SFˆSFˆTG‰TG‰TG‹VIXKXKWJŽXKXKZM‘]O•]O•_Q—`R˜^P–`R˜aR›dUžfW k\¥uf°wh²}m¶†v¿”‚Ë›‰Ò¥Úª•ß¯›â´ ç¶¢ãÀ¬í¼«ã½¬äŵãÏ¿íÓÃñ×ÇõÞÎüàÐþÚÊÿʺõº±ØżãëêìüûýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÆÆÆmjh•’º¸²¿½·€{xpkh]\Zþýûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯®¬¯®¬¬¬ªªª¨©©§¦¦¤¦¦¤¡¡ŸŸŸšš˜˜šš‹knq‰Œƒƒ‡‚‚†…ˆ‹ˆ‹ŽŒŽ”Ž–’˜“•›•—›£¡¡¥¤¤¨¥¥©¬¬°²³µ¶·¹»¼¾¿ÀÂÅÄÆÇÆÈÊÊÊÎÎÎÓÓÓÔÔÔØØØÙÙÙÛÛÛÝÝÝßßßàààâââåååæææèèèééééééêêêììììììíííïíîðîïïïíððîñðîñðîòñïòñïòñïòñïòñïóòðòñïòñïóòðòñïòñïñðîòñïòñïñðîðïíñðîñðîñðîðïíðïíðïíðïíïîìïîìîíëîíëíìêíìêíìêíìêìëéëêèìëéìëéìëéëêèëêèëêèëêèêéçêéçêéçéèæéèæèçåéèæéèæèçåèçåèçåçæäèçååäâæåãçæäæåãæåãåäâåäâåäâåäâäãáäãáäãáäãáãâàãâàâáßâáßâáßâáßàßÝâáßáàÞàßÝàßÝàßÝÞÝÛÞÝÛÞÝÛâáßÜÛÙßÞÜÝÜÚÝÜÚÛÚØßÞÜÚÙ×àßÝÛÛ×ÝÝÙÚÚÖÜÜØÙÙÕÝÝÙÛÛ×××ÓÙÙÕØØÔÛØÕÛØÕÙÖÓÛØÕØÕÒÙÖÓÙÖÓØÕÒÚ×ÔØÕÒØÕÒÙÖÓÖÔÎÚØÒÖÔÎ×ÕÏØÖÐÖÔÎÚØÒÒÐÊÖÔÎÕÓÍØÖÐÔÒÌÔÒÌÕÓÍÒÐÊmljmmmmmmoooppppppqqqqqqrrrsssuuuwvxyxz~}ƒ‚„ˆ†‘Šˆ“|—sn‰ZS€NGtG=wH>xI?zLB}MB€OD‚OD‚OD‚OCƒOCƒOCƒQE…RE‡RE‡TG‰UHŠPE‰RG‹TIUJŽVKVKXL’YM“ZN”[O•`R˜_Q—`Qš`Qš`Qš`QšbSœfW vg±vg±{l¶|m·~nº‡wÑΘ†Õ¡â¢Žã¡â¥‘榑è¤æ©•ê°œñ·¡õ¾¨üÕÁÿÜÈÿßÎÿÛÊû¿¯ñµ¥ç¼®ê´ðëæùýøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ½½½mjh•’º¶°À¼¶~yvmhea`^ÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿¿¿±°®°¯­¬¬ª««©¨¨¦¦¦¤¥¥£¢¢ žžœ››™—™™ŠŒŒpsv‹Ž‘„„ˆƒƒ‡…ˆ‹ˆ‹ŽŒŽ”Ž–’˜’”š–˜ž›£¡¡¥¥¥©ªª®®®²²³µ·¸º¾½¿À¿ÁÅÄÆÈÇÉÊÊÊÍÍÍÒÒÒÕÕÕ×××ÙÙÙÝÝÝßßßßßßàààâââåååæææçççéééêêêêêêììììììíííïíîðîïñðîòñïñðîñðîòñïòñïòñïóòðóòðóòðòñïòñïòñïóòðñðîòñïñðîñðîñðîñðîñðîñðîðïíðïíðïíðïíïîìïîìïîìîíëîíëîíëíìêìëéíìêìëéíìêìëéíìêìëéìëéëêèëêèêéçêéçéèæéèæêéçéèæèçåéèæèçåéèæçæäæåãèçåçæäçæäçæäæåãçæäåäâåäâäãáåäâäãáåäâãâàäãáãâàâáßâáßâáßâáßâáßáàÞáàÞâáßßÞÜßÞÜáàÞÞÝÛÞÝÛÝÜÚßÞÜàßÝÛÚØßÞÜÝÜÚÜÛÙÞÝÛÝÜÚÛÛ×ÜÜØÛÛ×ÛÛ×ÛÛ×ÝÝÙÛÛ×ÜÜØÕÕÑÙÙÕÙÙÕÚÚÖÝÚ×ÝÚ×Ú×ÔÚ×Ô×ÔÑ×ÔÑÛØÕÚ×ÔØÕÒ×ÔÑØÕÒÖÓÐØÖÐÚØÒÖÔÎØÖÐÔÒÌØÖÐÕÓÍÕÓÍÖÔÎÔÒÌ×ÕÏÔÒÌÓÑËÒÐÊÐÎÈkjhjjjlllmmmlllnnnnnnppppppppprrrrqsutvwvxzy{{y„}{†z•†œ‚{¨{t¡i_™YO‰MC~I?zK@~LALALAMANB‚NB‚MAOB„QD†RE‡SFˆNC‡MB†PE‰TIUJŽTIWK‘YM“VJVJ]O•`R˜_P™aR›aR›_P™`QšeVŸk\¦m^¨xi³|m·yiµ{k·‚p¿‹yÈ•Ö™…ÚœˆÝ¡â¥ç¢ä©•ê§“è­—ë³ñ¼¨è͹ùÚÉúÛÊûË»ý³£å±£ß¯¡Ý´¯ÂáÜïýýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿµµµmjh–“‘¼¸²Á½·}xulgdba_ÿþüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¼¼¼²±¯°¯­¬¬ª««©©©§¦¦¤¤¤¢¢¢ ŸŸšš˜˜šš‰‹‹qtw‹Ž‘……‰ƒƒ‡‡Š‹Ž‘•‘—’˜“•›—™Ÿœž¤¡¡¥¥¥©©©­¯¯³³´¶·¸º¾½¿ÁÀÂÄÃÅÉÈÊÌÌÌÎÎÎÒÒÒÕÕÕ×××ÙÙÙÜÜÜÞÞÞßßßàààãããåååçççèèèéééêêêêêêìììííííííïíîðîïñðîñðîñðîòñïòñïòñïòñïóòðòñïòñïòñïñðîòñïóòðñðîñðîñðîñðîñðîñðîñðîðïíðïíðïíðïíðïíðïíîíëïîìîíëïîìîíëíìêíìêíìêíìêíìêìëéìëéëêèìëéëêèêéçëêèêéçéèæêéçéèæéèæéèæéèæèçåçæäçæäçæäéèæçæäçæäçæäåäâæåãæåãåäâåäâäãáåäâäãáãâàãâàãâàãâàâáßáàÞáàÞâáßáàÞáàÞáàÞáàÞÞÝÛàßÝßÞÜàßÝÞÝÛÝÜÚàßÝÜÛÙÞÝÛÞÝÛÜÛÙÞÝÛÜÛÙÛÛ×ÜÜØÞÞÚÜÜØÙÙÕÛÛ×ÛÛ×ÛÛ×ÚÚÖÛÛ×ÙÙÕÙÙÕÛØÕÛØÕÜÙÖØÕÒÙÖÓÝÚ×ÖÓÐÛØÕ×ÔÑÕÒÏÕÒÏ×ÔÑÚØÒ×ÕÏÖÔÎÚØÒÑÏÉÙ×ÑÙ×ÑÕÓÍÔÒÌÔÒÌØÖÐÓÑËÓÑËÔÒÌÓÑËhgeihfihfkjhmljllllllmmmmmmnnnooopppqqqtttssssrtutvvuwxwy~€…„††„‡…‘zw“jgƒWN‚LCwKA|LB}MB€MB€NB‚L@€MAQE…SFˆQD†ND…ND…QFŠUJŽSHŒTIUITHŽSGUIYM•[O—[O—^Rš`Qš_P™_P™fW iZ¤hY£n^ªzj¶yh·wfµve´n½{Î}Ж‚×›‡Ü¨“ꟊ᧑몔訒쬖ð²œö½ªõƳþϽþÉ·ø±Ÿî² ï¨™ãª›åÜÕöùòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ²²²oih›•”»·±À¼¶|wtkfc`_]ÿþüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¼¼¼°°®¯¯­¬¬ª««©¨¨¦¥¥£¤¤¢¡¡ŸŸŸŸššš˜™›…†ˆpsv“ƒ†‰‚…ˆ‡ŠŠ•‘—‘“™•——™ŸŸ¥¢¢¦¦¦ª««¯°°´³´¶¹º¼¾½¿ÃÂÄÅÄÆÉÈÊÌÌÌÐÐÐÒÒÒÖÖÖØØØÚÚÚÝÝÝÞÞÞßßßàààãããåååçççèèèéééêêêëëëìììîìíïíîðîïñïðñðîñðîñðîòñïóòðòñïòñïóòðñðîñðîñðîñðîñðîñðîðïíðïíðïíñðîðïíðïíðïíðïíðïíïîìðïíïîìïîìîíëíìêíìêïîìíìêíìêíìêíìêíìêìëéëêèìëéìëéëêèêéçëêèêéçêéçéèæêéçéèæèçåéèæçæäçæäèçåçæäéèææåãæåãçæäæåãåäâæåãåäâåäâåäâäãáäãáãâàâáßäãáãâàãâàâáßáàÞáàÞáàÞãâàßÞÜàßÝáàÞÝÜÚàßÝßÞÜÞÝÛÞÝÛàßÝàßÝÛÚØÞÝÛÞÝÛÜÛÙÝÝÙÜÜØÜÜØÝÝÙÛÛ×ÙÙÕÛÛ×ÛÛ×ÛÛ×ÚÚÖÙÙÕÜÜØØØÔ××ÓÜÙÖÚ×ÔÚ×ÔÚ×ÔÖÓÐÖÓÐÚ×ÔÚ×ÔØÕÒ×ÔÑÝÚ×ÖÓÐ×ÕÏÖÔÎÖÔÎÙ×ÑÓÑËÖÔÎ×ÕÏØÖÐÐÎÈÓÑËØÖÐÒÐÊÒÐÊÔÒÌÓÑËhgegfdgfdhgehgehhhkkkkkkmmmlllmmmnnnppppppppprqsrqstsutsuvuwxwyxv‚~|ˆ~š…‚ž€w«ul cY”TJ…LALAL@€L@€MANB‚OB„PC…ND…ND…NC‡QFŠSHŒTIUIRFŒRFŒVJXL”WK“[O—]Q™_P™]N—^O˜bSœeV gX¢iY¥p`¬tc²q`¯ra°|kº‰wʉwÊ‹wÌ|Ñ›†Ýš…Ü–€Ú¢Œæ¥é¤Žè¥é­—ñ®›æ²Ÿêȶ÷ÔÂÿ¼ªù¦”ã ‘Û¢“Ý­¦ÇÊÃäûûûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ©©©oih—–»·±¿»µzurhc`dcaÿþüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ»»»°°®¯¯­¬¬ª««©©©§¦¦¤¦¦¤¡¡ŸŸŸŸššš—˜š‡ˆŠruxŽ‘”„‡Šƒ†‰ˆ‹ŽŠ•‘—‘“™”–œ˜š ž ¦££§§§«ªª®¯¯³³´¶¹º¼¿¾ÀÂÁÃÆÅÇÉÈÊÌÌÌÐÐÐÒÒÒÕÕÕÙÙÙÛÛÛÝÝÝÞÞÞáááàààãããåååçççééééééëëëìììíííîìíîìíðîïñïðòñïñðîñðîòñïóòðóòðóòðóòðòñïòñïñðîñðîñðîñðîñðîðïíïîìðïíðïíðïíïîìðïíðïíïîìðïíðïíîíëîíëíìêîíëîíëíìêìëéíìêíìêíìêíìêìëéíìêìëéëêèëêèêéçêéçëêèéèæéèæéèæèçåèçåçæäèçåèçåèçåèçåæåãçæäçæäæåãæåãåäâåäâåäâäãáåäâäãááàÞãâàãâàäãáäãáâáßàßÝáàÞáàÞâáßßÞÜàßÝàßÝÝÜÚáàÞÞÝÛàßÝÞÝÛßÞÜÝÜÚÛÚØßÞÜÝÜÚÝÜÚÞÞÚÜÜØÜÜØÛÛ×ÛÛ×ÜÜØÛÛ×ÛÛ×ÛÛ×ÙÙÕØØÔÜÜØ××ÓØØÔÞÛØÙÖÓÜÙÖÖÓÐÙÖÓ×ÔÑÛØÕÙÖÓ×ÔÑØÕÒØÕÒÖÓÐØÖÐÖÔÎ×ÕÏ×ÕÏ×ÕÏ×ÕÏÚØÒÑÏÉÕÓÍÔÒÌ×ÕÏØÖÐÐÎÈÖÔÎÒÐÊfecedbfechgegfdffdhhfjjhjjhiiikkklllmmmnnnnnnoooqqqqqqrrrrqssrtutvvuwwvx|{}€~‚†„ˆ‡„’„sm’a[€QI}KCwLAMB€KAND„ND…ND…ODˆQFŠRG‹RG‹TISHŒTHŽVJVJTHŽXL”ZN–[O—ZN–\P˜`TœcV eX¢iY¥n^ªra°q`¯q`¯wfµ€n¿‚pÁƒqÄ…sÆŽ{Е‚ו֙…ÚŸŠá¢ä§’駒é¤æ§’鱞Iú¨–瘆פ‘涣ø±Ÿð­›ìÆÀßøòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿý¤£¡pkh ›˜¸´®½¹³vspda^mljÿþüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ»»»±±±¯¯¯­­«««©¨¨¦§§¥¥¥£¢¢ ŸŸ˜šš˜™›„…‡svyŽ‘”…ˆ‹ƒ†‰‡ŠŠ‘—’˜‘“™”–œ™›¡Ÿ¥££§¨¨¬¬¬°¯¯³³´¶¹º¼¿¾ÀÃÂÄÅÄÆÉÈÊÍÍÍÏÏÏÓÓÓÖÖÖÙÙÙÛÛÛÛÛÛààààààáááãããæææçççééééééëëëìììíííîìíïíîðïíñðîñðîñðîòñïóòðòñïòñïôóñóòðòñïòñïòñïòñïñðîñðîòñïñðîðïíñðîðïíðïíïîìïîìïîìïîìïîìîíëîíëîíëïîìîíëîíëíìêìëéíìêíìêìëéìëéìëéìëéìëéëêèìëéêéçéèæêéçéèæêéçéèæèçåèçåèçåèçåçæäçæäçæäæåãæåãæåãçæäåäâåäâæåãäãáäãáåäââáßâáßãâàâáßäãáãâààßÝáàÞâáßáàÞãâàßÞÜáàÞàßÝßÞÜßÞÜÞÝÛÞÝÛáàÞÜÛÙßÞÜÝÜÚáàÞÚÙ×ÜÛÙÜÜØÝÝÙÛÛ×ßßÛÛÛ×ÜÜØÚÚÖÛÛ×ÛÛ×ØØÔØØÔÙÙÕÛØÕÜÙÖÜÙÖØÕÒÛØÕØÕÒØÕÒ×ÔÑÚ×ÔÖÓÐÖÓÐØÕÒÚ×ÔÖÓÐÙÖÓÚ×ÔÔÒÌÕÓÍ×ÕÏÖÔÎÔÒÌÖÔÎÔÒÌÕÓÍ×ÕÏÖÔÎÎÌÆÖÔÎÒÐÊedbdcadcafecfecffdffdhhfhhfhhhiiijjjkkkllllllmmmnnnoooppppoqqprrqssrtsrtutvvtxyw{zw…|Š€zŸƒ}¢{s§kc—ZOOD‚J@€MCƒND…ND…PE‰RG‹RG‹RG‹TIUJŽUIUIVJUIXL”YM•VJ’YM•\P˜_S›cV fY£hX¤k[§m\«n]¬q`¯tc²we¶|j»o„rʼnvËŒyÎyÎ|Ñ™„ÛŸŠá¥ç©”릑è¤æ¤‘â­šë¢á™‡ØŠß°ò±Ÿð®œí©£ÂÖÐïýýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýŸžœojg ›˜¹µ¯¼¸²tqna^[vusÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþººº°°°®®®®®¬««©ªª¨§§¥¦¦¤¢¢ ŸŸ˜šš˜™›‚ƒ…wz}Ž‘”…ˆ‹„‡Šˆ‹Ž‹Ž‘’˜“•›‘“™•—™›¡Ÿ¥¤¤¨¦¦ª¬¬°°°´³´¶¹º¼¿¾ÀÃÂÄÇÆÈÊÉËÍÍÍÐÐÐÓÓÓ×××ØØØÚÚÚÝÝÝàààßßßâââäääæææçççèèèêêêëëëììììììîìíïíîñðîñðîñðîñðîòñïòñïòñïóòðôóñòñïòñïòñïòñïòñïñðîñðîòñïòñïñðîðïíðïíðïíðïíðïíïîìïîìïîìïîìîíëîíëïîìïîìîíëíìêíìêìëéíìêíìêìëéìëéëêèëêèìëéëêèêéçêéçêéçêéçéèæéèæéèæèçåçæäèçåèçåçæäçæäçæäçæäçæäæåãåäâåäâäãáåäâäãáäãáâáßäãáãâàâáßãâàâáßáàÞâáßáàÞáàÞâáßàßÝâáßßÞÜßÞÜàßÝßÞÜÝÜÚÝÜÚÞÝÛßÞÜÞÝÛÚÙ×ÛÚØßÞÜÞÞÚÞÞÚÛÛ×ÜÜØÛÛ×ÜÜØÚÚÖÛÛ×ÛÛ×ÙÙÕÚÚÖÙÙÕÜÙÖÝÚ×ØÕÒÝÚ×Ú×ÔÖÓÐ×ÔÑÛØÕÚ×Ô×ÔÑÙÖÓØÕÒÙÖÓÖÓÐØÕÒØÕÒÓÑËÖÔÎØÖÐÒÐÊÔÒÌÔÒÌÕÓÍÕÓÍÔÒÌÓÑËÑÏÉÕÓÍÔÒÌdcacb`dcaccaddbeecffdffdffdffffffgggiiiiiijjjjjjkkkkkklllmmmoooppppppqqqrrrsrttsutsuvuwyw{~|€‡……‹ƒ“}{jf‹[W|OG‚ME€MC„PF‡RH‰RH‰SHŒUJŽVJUIVJXL’XL’WK‘VJWK‘[O—_S›aUcWŸaTžfY£l\¨n^ªp_®tc²zh¹~l½‚pÇuÈŠwÌŠwÌŠwÌŠwÌŽzÏ—ƒØˆß¡Œã§“ê©•ì¡ä¢Žå¨”ë¡äš†Ý Œã¦’鬘肋棑äÉÄßøóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿý™˜–nhg¢œ›¹´±¹´±spm^[X~|ÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþ¸¸¸±±±®®®¬¬ª««©©©§¨¨¦¦¦¤¡¡ŸŸŸ˜šš™šœ€ƒy|’•„‡Š„‡Š‰‹‘•Ž–‘“™“•›•—šœ¢Ÿ¡§¤¤¨§§«¬¬°°°´´µ·¹º¼À¿ÁÃÂÄÆÅÇÊÉËÍÍÍÐÐÐÔÔÔÖÖÖØØØÛÛÛÞÞÞÞÞÞÞÞÞáááåååæææçççéééêêêëëëìììíííîìíïíîñðîñðîñðîñðîòñïòñïóòðòñïóòðóòðòñïóòðòñïòñïñðîòñïòñïñðîðïíðïíðïíïîìïîìðïíïîìïîìïîìïîìïîìîíëîíëîíëíìêíìêíìêíìêíìêíìêìëéëêèëêèìëéìëéêéçêéçëêèêéçéèæéèæéèæèçåèçåèçåèçåèçåçæäçæäçæäæåãæåãåäâåäâåäâåäâäãáãâàäãáãâàäãáäãááàÞâáßáàÞâáßâáßáàÞàßÝáàÞàßÝàßÝáàÞßÞÜßÞÜßÞÜÝÜÚßÞÜßÞÜÝÜÚÝÜÚÜÛÙÝÜÚßÞÜßßÛÛÛ×ÝÝÙÛÛ×ÛÛ×ÙÙÕÜÜØÜÜØÚÚÖÚÚÖÝÚ×Ú×ÔÞÛØÙÖÓÙÖÓÜÙÖÚ×ÔÙÖÓÙÖÓÛØÕ×ÔÑÚ×ÔÕÒÏÛØÕ×ÔÑÕÒÏÚ×ÔÔÑÎÔÑÎ×ÔÑÕÓÍÕÓÍÖÔÎÔÒÌØÖÐÖÔÎÓÑËÖÔÎÑÏÉÓÑËÒÐÊ`_]a`^a`^aa_ddbccaeecffdeecffffffhhhiiigggiiiiiiiiijjjjjjkkkllllllooooooppppoqpoqsrtsrttrvvtxww}zz€yw‰}{ { sk¦c[–UKŒOE†ND…QGˆSHŒUJŽUIXL’XL’VJWK‘WK‘XL’YM“ZN–[O—]Q™_S›aTžcV jZ¦l\¨q`¯tc²zh¹ƒq†tLJuÈ‹xÍ‹xÍzÏŽ{Б}Ò”€Õœ‡Þ£Žå¥‘謘ﮚñ¦’é¡ä Œãœˆßœˆß¡ä¦’驗꧕覡¼ÐËæþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþü”“‘oih¤ž¹´±·²¯rol\YV†…ƒÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþ···°°°­­­««©««©©©§§§¥¦¦¤¢¢ œžž˜šš›œž€ƒz}€Ž‘”„‡Š†‰Œ‹“•’˜’”š’”š•—šœ¢ž ¦¤¤¨¨¨¬­­±±±µµ¶¸¹º¼ÁÀÂÃÂÄÇÆÈÉÈÊÍÍÍÑÑÑÕÕÕØØØØØØÝÝÝÞÞÞÝÝÝßßßãããåååççççççèèèêêêììììììíííïíîïíîðïíñðîñðîòñïòñïòñïòñïòñïóòðóòðóòðòñïòñïòñïñðîñðîñðîñðîðïíðïíðïíïîìïîìïîìðïíïîìïîìïîìïîìíìêîíëîíëíìêíìêíìêíìêíìêëêèêéçëêèëêèëêèìëéëêèêéçêéçêéçêéçéèæéèæèçåèçåèçåèçåçæäçæäæåãæåãåäâæåãåäâæåãæåãåäâãâàãâàäãáåäâãâàãâàâáßâáßâáßãâàáàÞâáßßÞÜàßÝáàÞáàÞßÞÜáàÞÞÝÛÞÝÛÞÝÛáàÞÞÝÛßÞÜÞÝÛÜÛÙÝÜÚÜÛÙÜÜØÝÝÙÛÛ×ÛÛ×ÞÞÚÛÛ×ÜÜØÜÜØÚÚÖÛÛ×ÙÖÓÜÙÖßÜÙØÕÒÛØÕÚ×ÔÜÙÖØÕÒÚ×ÔÙÖÓÛØÕÕÒÏÕÒÏÚ×ÔÚ×ÔÓÐÍÚ×Ô×ÔÑÕÒÏÖÓÐÔÒÌØÖÐÕÓÍÕÓÍÖÔÎÖÔÎÒÐÊÓÑËÔÒÌÓÑËÕÓÍ^][_^\^][__]aa_bb`bb`ddbddbeeeeeeggggggfffgggggghhhhhhiiiiiijjjkkklllmmmmmmmmmoooonppoqrqssrttsutsuvtxwuyyy}}}€Š„…€–xwf_YRƒSI‰RHˆTIUJŽVKTIXL’[O•[O•]Q—\P–ZN”\P˜^Rš`SbUŸgZ¤j]§m_«rd°€n¿‰wȈuÊŠwÌ|Ñ}Ò|Ñ|Ñ•Ö˜„Ù£Žå«–í®šñ´ ÷±ô­™ð¥‘蜈ߙ…Üš†Ý›‡Þ›‡Þ™ˆÞ¨—í ‘á ‘áéåöýùÿÿÿÿÿÿÿÿÿÿÿÿÿÿþüŒ‹‰oih¦ Ÿ·´±³°­pmkXUSŽŒÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýýýµµµ²²²¯¯¯­­­­­­ªªª§§§§§§¢¢¢ž  ™››š›€‚|‚“†‰Œ‡Š‹“•‘“™’”š•—–˜žšœ¢Ÿ¡§£¦©§ª­¬¬°±±µµ¶¸º»½¾¿ÁÁÂÄÇÆÈÊÉËÍÍÍÐÐÐÕÕÕÖÖÖØØØÜÜÜÜÜÜÞÞÞáááãããåååçççèèèéééêêêììììììíííïîìðïíðïíñðîòñïòñïòñïñðîòñïòñïóòðóòðóòðòñïòñïòñïñðîðïíñðîðïíðïíðïíðïíðïíïîìïîìðïíïîìîíëïîìîíëîíëïîìíìêíìêíìêíìêìëéìëéëêèëêèìëéìëéëêèìëéëêèêéçéèæêéçêéçéèæèçåèçåèçåèçåçæäçæäæåãæåãçæäçæäåäâæåãæåãæåãåäâãâàãâàäãáãâàâáßãâàâáßàßÝâáßãâàâáßâáßàßÝáàÞâáßÝÜÚßÞÜßÞÜßÞÜßÞÜÝÜÚàßÝÝÜÚÞÝÛÝÜÚÜÛÙÝÜÚÜÛÙÜÜØÞÞÚÚÚÖÞÞÚÛÛ×ÙÙÕÜÜØÚÚÖßÜÙÙÖÓÛØÕÛØÕÛØÕØÕÒÜÙÖØÕÒÙÖÓÜÙÖØÕÒØÕÒ×ÔÑØÕÒÖÓÐÙÖÓØÕÒ×ÔÑ×ÔÑÕÒÏÕÒÏ×ÔÑÕÓÍÖÔÎÓÑËÔÒÌÔÒÌÕÓÍÕÓÍÓÑËÕÓÍÐÎÈ×ÕÏ\[Y^][\[Y[[Y]][^^\__]aa_aa_bbbddddddfffeeeggggggggghhhhhhiiiiiiiiijjjjjjlllmmmmmmonponppoqpoqqprrqssquuswsswttxst~xyƒzy~}“x©|u¦rh¨e[›ZO“UJŽRG‹UJŽWK‘XL’ZN”^R˜_S™_S™]Q™\P˜`ScV k^¨m`ªoa­wiµ‡uÆ}Γ€Õ|Ñ“€Õ¨•ê¤‘æ¡Žã£ä›‡Üª•ì¶¡ø­™ð¬˜ïº¦ý½©ÿ»§þ°œó¡ä‰à™…Ü”€×”ƒÙ£’裔䚋۾ºËû÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿþüƒ‚€nhg¨¢¡·´±±®«oljXUS˜—•ÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýýý±±±²²²¯¯¯­­­¬¬¬ªªª¨¨¨¥¥¥¢¢¢ŸŸšœœš›}~€€ƒ†Ž‘”†‰Œ†‰Œ‹“‘—‘“™’”š”–œ—™Ÿ›£¡£©¤§ª¦©¬­­±±±µµ¶¸º»½¾¿ÁÂÃÅÇÆÈÊÉËÍÍÍÑÑÑÕÕÕÕÕÕÚÚÚÜÜÜÛÛÛßßßâââãããåååçççèèèêêêëëëììììììíííïîìðïíñðîñðîñðîòñïòñïñðîòñïóòðòñïòñïôóñóòðñðîòñïðïíðïíñðîðïíðïíïîìïîìðïíïîìïîìïîìïîìîíëïîìîíëîíëíìêíìêîíëíìêìëéìëéìëéëêèìëéìëéëêèëêèëêèêéçéèæêéçêéçêéçéèæèçåèçåèçåæåãèçåçæäçæäçæäçæäåäâåäâåäâåäâæåãåäâãâàãâàäãáãâàäãáãâàáàÞãâàâáßãâàâáßàßÝâáßáàÞàßÝÞÝÛàßÝàßÝßÞÜàßÝÜÛÙàßÝÝÜÚÞÝÛßÞÜÝÜÚÜÛÙÝÜÚÞÞÚÛÛ×ÝÝÙÜÜØÜÜØÙÙÕÜÜØÜÜØÜÙÖÜÙÖÜÙÖÝÚ×ÛØÕÚ×ÔÚ×ÔÜÙÖÙÖÓÛØÕÛØÕÔÑÎÖÓÐÙÖÓ×ÔÑÚ×ÔÚ×ÔØÕÒÔÑÎØÕÒØÕÒÓÐÍ×ÕÏÔÒÌÖÔÎÕÓÍÔÒÌ×ÕÏÒÐÊÕÓÍÒÐÊÑÏÉÕÓÍYXVZYW[ZXZZXZZX[[Y\\Z^^^^^^aaabbbbbbddddddccceeeffffffhhhggghhhiiihhhiiiiiikkkkkkkkkmmmnnnooonmoonppoqqprrqssrtsqutrvuuyuuyzz€€€†‚Œ„…€}™vse^[T…UK‹SI‰XM‘[P”_S™aU›_S™]Q—`TœcWŸi]¥oc«re¯~q»Ž}Ì¡ßµ£ôŸÞ¢á·¥ö¸§ö»ªùÇ·ÿ¦–ß± ïòÿ¯žíº©ø×ÉÿÕÇÿÖÉÿÕÈÿ¼­ó©šà¡æš‰ß~×}Ö’€Ù‘ØœÌÕÉÿþûÿÿüÿÿÿÿÿÿÿýýý|||ihf¤£¡¸µ²®«¨jigRQO˜˜–ÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüüü¬¬¬±±±®®®­­­¬¬¬©©©§§§¦¦¦£££ž  šœœ›œž{|~„‡Ž‘”…ˆ‹†‰Œ‹“•‘’š‘’š“•›˜š ›£ ¢¨¤§ª§ª­­­±³³··¸ºº»½¾¿ÁÁÂÄÇÇÇÊÊÊÎÎÎÒÒÒÔÔÔÕÕÕÜÜÜÛÛÛÛÛÛßßßâââäääåååçççèèèêêêëéêíëìíìêîíëïîìñðîñðîñðîñðîòñïòñïñðîòñïòñïóòðóòðóòðòñïñðîñðîðïíñðîñðîðïíïîìðïíïîìïîìïîìïîìïîìïîìïîìïîìîíëíìêìëéîíëîíëíìêìëéìëéìëéìëéëêèìëéëêèëêèëêèêéçêéçêéçêéçéèæéèæéèæèçåèçåæåãèçåçæäèçåæåãåäâåäâæåãäãáåäâåäâäãáäãáäãáåäâãâàãâàãâàãâàâáßáàÞãâààßÝàßÝáàÞâáßàßÝâáßÞÝÛßÞÜßÞÜßÞÜÞÝÛàßÝÝÜÚáàÞÛÚØÝÜÚÜÜØßßÛÜÜØÜÜØÝÝÙÛÛ×ÛÛ×ÛÛ×ßÜÙÞÛØÝÚ×ÛØÕßÜÙÚ×ÔÛØÕÛØÕÜÙÖÛØÕÛØÕÚ×ÔÜÙÖÕÒÏÕÒÏÛØÕØÕÒ×ÔÑØÕÒÜÙÖÒÏÌØÕÒÖÓÐÔÑÎÚ×ÔÓÐÍÓÑËÓÑËÕÓÍÙ×ÑÒÐÊÑÏÉÔÒÌÕÓÍÑÏÉVUSXWUXWUXXVXXVYYW[[YYYYZZZ]]]______```bbbbbbbbbdddcccfffeeefffhhhggghhhhhhjjjiiikkkjjjllllllmlnnmoonppoqqprrqsqosqosqquqqurrxttzuv€wx‚xu‘|y•|u¦{t¥oe¥aW—\Q•ZO“ZN”^R˜`Tš`TšbVžeY¡h\¤l`¨uh²„wÁ—†Õ¨—渦÷¨–ç´¢ó³¡ò¾­üÈ·ÿÐÀÿ½­ö´£ò»ªùª™èÀ¯þÖÈÿÑÃÿÐÃýÕÈÿÒÃÿ¯ æ°Ÿõª™ïšˆá—…Þ‘Ø}Ö‘…Á§›×ÑÎÕðíôþþþÿÿÿýýýxxxedb¡ ž¹¶³«¨¥kjhPOM  žÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûûûªªª±±±¯¯¯®®®«««©©©§§§¦¦¦¤¤¤ž  šœœ›œž|}…ˆ‹“†‰Œ‡ŠŒŽ”‘—’“›”••—˜š œž¤Ÿ¡§£¦©§ª­®®²²²¶·¸º»¼¾¿ÀÂÂÃÅÈÈÈËËËÎÎÎÑÑÑÕÕÕ×××ÜÜÜÜÜÜÛÛÛàààâââäääåååæææèèèêêêëéêìêëîíëîíëïîìðïíñðîñðîñðîòñïòñïòñïóòðòñïòñïóòðòñïñðîñðîðïíñðîðïíðïíïîìïîìïîìïîìïîìîíëïîìïîìïîìïîìïîìîíëîíëíìêîíëíìêíìêìëéìëéìëéìëéëêèíìêéèæêéçëêèêéçëêèêéçêéçéèæêéçéèæèçåçæäçæäèçåèçåçæäæåãåäâæåãæåãåäâåäâäãáäãáäãáäãáãâàãâàãâàãâàãâàâáßâáßãâàáàÞáàÞáàÞáàÞàßÝáàÞÝÜÚàßÝÞÝÛßÞÜÝÜÚâáßÜÛÙÝÜÚÝÜÚÝÜÚÝÝÙÜÜØÞÞÚÝÝÙÞÞÚÜÜØÙÙÕÝÝÙâßÜÚ×ÔÛØÕÚ×ÔÙÖÓÚ×ÔÛØÕÜÙÖÚ×ÔÛØÕÜÙÖÙÖÓØÕÒÖÓÐÖÓÐÛØÕÕÒÏÖÓÐÙÖÓÙÖÓÑÎËÕÒÏ×ÔÑ×ÔÑÖÓÐÖÓÐÔÒÌÖÔÎØÖÐÓÑËÑÏÉÓÑËÔÒÌÐÎÈÕÓÍWUVWUVWUVWWWVVVWWUXXVXXXXXXZZZ\\\\\\]]]______```aaaaa_bb`bbbcccfffeeefffggghhhggghhhjjjjjjjjjkkkmmmnmomlnmlnonppoqqprqprqprpptrrvrrvsswvv|ww}{z‚}|„~Ž€yt›pk’e\“aX`U™_T˜bVœeYŸi]¥ma©uh²†yæ—ಣ츨ô­é˼ÿ˼ÿ̼þ̼þÑÃÿÐÂþ¹ªï³¤é´¥îÆ·ÿÑÅû×ËÿâÙÿðçÿðéÿÜÕðÇ»÷¹­é®Ÿé¥–à›‹Þ•…ØÔ|ÑŸ“Óµ©éÏËâéåüîëù­ª¸•’ ¢Ÿ­´±µ¦£§ihfMLJ¬¬ªÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúúú«««±±±¯¯¯¬¬¬¬¬¬«««¨¨¨§§§¤¤¤ž  ™›››œž|}„‡ŠŽ‘”†‰Œˆ‹ŽŒŽ”Ž–‘’š“”œ•—˜š œž¤¡£©¤¦¬ª¬²°°´²²¶·¸º¼½¿¿ÀÂÃÄÆÇÇÇËËËÎÎÎÓÓÓÕÕÕ×××ÛÛÛÛÛÛÝÝÝáááãããåååæææçççéééêêêìêëìêëíìêîíëðïíñðîñðîñðîòñïóòðòñïòñïòñïòñïóòðóòðòñïñðîñðîðïíðïíïîìðïíïîìðïíïîìðïíïîìïîìïîìðïíîíëïîìîíëîíëíìêíìêíìêíìêìëéìëéìëéëêèëêèíìêëêèêéçëêèêéçêéçëêèéèæèçåêéçêéçéèæèçåèçåèçåèçåçæäçæäæåãæåãçæäåäâæåãæåãåäâåäâäãáâáßäãáâáßãâàãâàãâàâáßãâàãâààßÝáàÞáàÞàßÝáàÞàßÝßÞÜàßÝÞÝÛàßÝÞÞÚààÜÛÛ×ààÜÝÜÚÜÛÙÝÝÙÜÜØßßÛÝÝÙÜÜØØØÔÜÜØÝÝÙÜÙÖÚ×ÔßÜÙÙÖÓÛØÕÚ×ÔÛØÕÝÚ×ÛØÕÜÙÖÙÖÓÚ×ÔÕÒÏÚ×ÔØÕÒÖÓÐØÕÒ×ÔÑÙÖÓÖÓÐ×ÔÑÚ×ÔÖÓÐ×ÔÑÑÏÉÖÔÎÕÓÍÓÑËÔÒÌÑÏÉÒÐÊÓÑËÖÔÎÐÎÈØÖÐQOPVTUVTUUUUUUUVVTSSQUUUXXXWWWYYYYYYZZZ[[[^^^^^^^^^^^\__]aaaaaabbbddddddffffffggghhhiiihhhjjjkkkjjjkjllkmlkmmlnmlnonponppoqnnroosoosoosppvrrxsrzut|ut„xw‡vq˜zuœyp§vm¤nc§eZžfZ i]£nbªpd¬xkµƒvÀ ‘Ú¯ é²¢îµ¥ñ˼ÿ˼ÿξÿ̼þȺöÑÃÿßÐÿÕÆÿÖÇÿàÑÿçÛÿæÚÿçÞÿðçÿùòÿôíÿäØÿã×ÿäÕÿ×Èÿ©™ì”„×’Ö‹zÏŠ~¾˜ŒÌ±­Ä¶²É·´ÂÅÂÐßÜêÕÒàÈÅɵ²¶rqoGFD¶¶´ÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùùù«««±±±®®®¬¬¬«««©©©¨¨¨§§§¢¢¢Ÿ¡¡šœœœŸxy{†‰ŒŽ‘”†‰Œ‰ŒŒŽ”‘—“”œ”••—˜š Ÿ¥¡£©¥§­¨ª°¯¯³²²¶·¸º¼½¿¿ÀÂÂÃÅÈÈÈËËËÎÎÎÓÓÓÔÔÔÛÛÛÚÚÚÛÛÛÞÞÞáááãããäääæææèèèéééëëëíëìíëìîíëïîìðïíñðîñðîñðîòñïóòðòñïòñïòñïòñïòñïñðîñðîñðîðïíðïíîíëðïíðïíïîìðïíðïíïîìïîìïîìîíëïîìîíëîíëîíëíìêíìêíìêìëéìëéìëéìëéëêèëêèìëéíìêëêèêéçêéçêéçêéçêéçéèæéèæêéçêéçæåãèçåèçåèçåçæäçæäçæäæåãæåãæåãåäâåäâåäâåäâåäâãâàäãáãâàãâàäãáäãááàÞâáßâáßáàÞàßÝáàÞàßÝâáßßÞÜàßÝßÞÜßÞÜàßÝàßÝÝÝÙààÜÝÝÙßßÛÝÜÚÞÝÛÞÞÚÝÝÙÜÜØÞÞÚÝÝÙÙÙÕÛÛ×ÛÛ×ÜÙÖÜÙÖÛØÕÛØÕÝÚ×Ú×ÔÜÙÖÝÚ×Ú×ÔÚ×ÔØÕÒÙÖÓÕÒÏÜÙÖ×ÔÑÙÖÓÖÓÐØÕÒÕÒÏÕÒÏ×ÔÑØÕÒÔÑÎÕÒÏÓÑË×ÕÏÕÓÍÕÓÍÔÒÌÒÐÊÒÐÊ×ÕÏÒÐÊÒÐÊÑÏÉ999>>>IIIPNOVTUXXXTTTUUUWWWVVVUUUWWWWWWXXX[[[]]][[[\\\]]]^^^___```aaaaaaccccccddddddffffffggggggiiijjjlllkkkjjjjjjkkklkmmlnonponpomqomqmmqoosppvqqwrrxttzts{vu}xv‚|z†zyyxŽsm˜sm˜ri tk¢yl®‚u·©œÜÏÂÿßÓÿßÓÿà×þðçÿøóÿ÷òÿñêÿæßøòèÿêàüóëÿýõÿþûÿûøÿóîüìçõöñÿîé÷òëþýöÿþûÿþûÿïëÿÿךŽÖ‘…̓wÅ…yǜج è¢—Û£˜Üµ«å¸®è½´ëżó¹³Ø š¿ÓÒàûúÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿ÷÷÷«««±±±¯¯¯­­­¬¬¬«««¨¨¨§§§£££ž  œžžœŸwxzˆ‹Ž“‡ŠŠŽ–‘—’“›”••—™›¡Ÿ¥¡£©¤§ª©¬¯¯¯³³³·¸¹»½¾À¿ÀÂÂÃÅÈÈÈËËËÎÎÎÓÓÓÒÒÒÜÜÜÚÚÚÛÛÛßßßâââãããåååçççèèèéééëëëììêîîìïîìïîìñðîòñïñðîñðîóòðóòðòñïòñïóòðòñïòñïòñïòñïïîìðïíðïíïîìðïíðïíðïíðïíïîìïîìïîìïîìîíëîíëîíëîíëîíëíìêíìêìëéíìêíìêìëéíìêìëéìëéëêèìëéëêèêéçêéçëêèêéçéèæêéçêéçéèæèçåèçåèçåèçåéèæèçåæåãçæäæåãæåãæåãåäâçäâçäâåäâåäâäãáãâàãâàäãáãâàãâààßÝäãáäáßãàÞáàÞáàÞáàÞáàÞàßÝßÞÜáàÞÝÜÚßÞÜßÞÜÞÝÛàßÝÞÝÛÝÜÚÝÝÙÞÞÚàÝÚáÞÛÚÚÖÜÜØÛÛ×ÜÜØÞÛØÝÚ×ÛØÕÝÚ×ÜÙÖÛØÕÜÙÖÛØÕÜÙÖÚ×ÔÚ×ÔÜÙÖÛØÕÙÖÓØÕÒÙÖÓ×ÔÑ×ÔÑÔÑÎ×ÔÑÔÑÎÕÒÏ×ÔÑÓÐÍÙÖÓÕÒÏÓÑËÕÓÍÖÔÎÕÓÍÕÓÍÑÏÉÕÓÍÕÓÍÑÏÉÐÎÈÑÏÉ555555555756><=EEELLLTTTWWWVVVVVVWWWWWWVVVWWWYYYZZZZZZ[[[[[[]]]]]]^^^^^^```aaabbbbbbeeedddfffgggggggggjjjhhhiiijjjkkkjikkjllkmlkmmkoomqmmqmmqnntoouoouppvpowrqyrp|sq}po…rq‡qk–uošxo¦{r©}p²„w¹¤—ןøïãÿðäÿóêÿúñÿü÷ÿü÷ÿûôÿðéÿðæÿîäÿòêÿúòÿýúÿþûÿþùÿøóÿóîüîé÷öïÿþ÷ÿþûÿþûÿúöÿñíÿÎÂÿµ©ñ¢–䘌ڗ‹ÓŸ“ۘѓˆÌž”Î¥›Õµ¬ã¾µì½·ÜÈÂçÐÏÝÕÔâëêìúùûýýýþþþÿÿÿÿÿÿôôô¨¨¨¯¯¯®®®­­­­­­ªªª¨¨¨¦¦¦£££ž  œžžœŸuvx‰Œ“†‰ŒŠ•’˜“”œ–—Ÿ—™Ÿ›£Ÿ¡§¢¤ª¥¨«©¬¯¯¯³³³·¸¹»¼½¿ÀÁÃÃÄÆÇÇÇÊÊÊÏÏÏÒÒÒÕÕÕÛÛÛØØØÛÛÛßßßâââäääåååçççéééêêêëëëììêîîìïîìðïíñðîòñïòñïòñïòñïóòðòñïòñïòñïñðîòñïðïíîíëðïíñðîïîìðïíðïíñðîñðîñðîïîìïîìîíëîíëïîìîíëîíëîíëîíëíìêìëéìëéíìêìëéìëéìëéìëéëêèêéçëêèëêèêéçëêèëêèéèæéèæêéçêéççæäéèæèçåèçåèçåéèæçæäçæäçæäæåãçæäæåãæåãèåãçäâåäâäãáäãáãâàäãáãâàâáßãâàâáßâáßäáßâßÝâáßáàÞáàÞßÞÜáàÞàßÝßÞÜÞÝÛàßÝÞÝÛÝÜÚßÞÜÞÝÛÜÛÙÜÜØááÝÜÙÖÞÛØÜÜØÝÝÙÝÝÙÝÝÙÝÚ×ÜÙÖÜÙÖÜÙÖÝÚ×Ú×ÔÝÚ×ÛØÕÛØÕÛØÕÙÖÓßÜÙ×ÔÑÝÚ×ÔÑÎÚ×Ô×ÔÑÔÑÎ×ÔÑÖÓÐ×ÔÑ×ÔÑÖÓÐÕÒÏÖÓÐÕÒÏÓÑËÕÓÍÖÔÎÔÒÌÑÏÉÒÐÊÑÏÉÒÐÊÒÐÊÓÑËÑÏÉ756775775444444444666;;;AAAKKKSSSWUVYWXXVWWUVWWWWWWXXXYYYYYY[[[YYY[[[]]]^^^^^^______aaadddddddddffffffgggggghhhiiijjjihjkjlkjlkjlmlnlkmmlnnmommqllpnnrnnrnntppvqpxpowpowpowopzqr|qp~ts|y”€}˜”Á´«ØßÕ÷éßÿùôÿþùÿþþþþþþüúþõó÷óíþìæ÷èßøîåþúöÿû÷ÿöòýïëöéáøéáøéäùõðÿþýÿþýÿøõüîëòëäÿêãþäÛÿÝÔûÑÇ÷Ƽ찦ášË“‡Í›Õ£—ݯ£éªžä®¢è«¢á­¤ã½µê¼´éÇÀçžåÕÒçîëÿêè󪨳®®´¬¬²­­­«««ªªª¨¨¨§§§£££Ÿ ¢›œžœŸtuw‹Ž‘“†ˆŽŠŒ’•‘“™”••–ž˜š ›£ž ¦£¥«¦¨®©«±°°´´´¸¸¹»½¾ÀÀÁÃÃÄÆÊÊÊÌÌÌÏÏÏÑÑÑØØØØØØØØØÝÝÝßßßâââäääæææèèèéééêêèëëéííëííëïîìñðîñðîñðîóòðòñïòñïòñïòñïòñïòñïñðîëëéÒÒÐÄÄÂîîìðïíðïíòñïñðîñðîñðîðïíïîìîíëîíëîíëíìêíìêíìêíìêíìêìëéìëéíìêìëéìëéìëéìëéìëéëêèêéçëêèìëéêéçêéçêéçêéçéèæéèæéèæéèæéèæèçåèçåèçåèçåçæäèçåçæäçæäèçååäâçæäèåãæãáçäâçäâæãáäáßæãáæãáåâàåâàæãáäáßäáßãàÞáÞÜäáßâßÝâßÝãàÞáÞÜãàÞáÞÜáÞÜáÞÜáÞÛãàÝÞÛØÞÛØßßÛÝÝÙÝÚ×ßÜÙÞÛØáÞÛÞÛØÞÛØÝÚ×ÜÙÖÝÚ×ÝÚ×ÛØÕÚ×ÔÜÙÖÚ×ÔÝÚ×ÝÚ×ÙÖÓØÕÒÚ×Ô×ÔÑÖÓÐÖÓÐÚ×ÔÕÒÏ×ÔÑØÕÒÙÖÓÖÓÐÓÐÍ×ÔÑÕÒÏÕÒÏÕÓÍ×ÕÏÒÐÊÓÑËÖÔÎÑÏÉÑÏÉÔÒÌÖÔÎÒÐÊÑÏÉ756664553555666666666777444444888@>?HFGOMNWUVXXXXXXXXXXXXWWWXXXZZZYYY[[[ZZZ\\\]]]^^^___```aaaaaabbbcccdddeeeffffffhhhihjjikkjlihjjikjikjiklkmkkojjnllpllpmmsnntnmunmunmunmulmwnoymlzmlzol‡qn‰sj—{rŸ”Š¬°¦ÈØÓàòíúûûûúúúòðôóñõøòÿúôÿöíÿêáúîêõðì÷çãîìèóõíÿõíÿíèýèãø÷öøûúüóð÷ôñøñêÿïèÿèßÿìãÿñçÿíãÿãÙÿÕËÿµ©ï¤˜Þ¡•Û¢–Ü£—Ý¡•Û›’Ñ¡˜×¯§Ü®¦ÛĽäÀ¹à¾»Ð¶³È¼ºÅ¾¼Ç¿¿Å³³¹²²²¬¬¬©©©©©©§§§£££žŸ¡›œžœŸuvxŽ‘”“ˆŠ‹“Ž–‘“™”•–—Ÿ™›¡šœ¢Ÿ¡§£¥«¦¨®«­³°°´µµ¹¹º¼¼½¿ÀÁÃÄÅÇÉÉÉÌÌÌÎÎÎÏÏÏØØØØØØÙÙÙßßßàààáááäääæææèèèéééêêèëëéííëííëïîìðïíñðîòñïòñïòñïòñïóòðòñïòñïðïíáàÞÁÁ¿¸¸¶¸¸¶ááßñðîòñïóòðòñïñðîðïíîíëîíëîíëíìêíìêìëéìëéíìêíìêìëéìëéìëéìëéìëéìëéìëéëêèëêèêéçêéçëêèìëéêéçêéçêéçêéçêéçéèæèçåêéççæäçæäèçåèçåèçåèçåçæäçæäæåãæåãæåãæåãçäâçäâæãáçäâäáßæãáæãáåâàäáßåâàåâàáÞÜäáßãàÞáÞÜãàÞãàÞãàÞâßÝãàÞàÝÛâßÝàÝÛâßÝâßÜÞÛØÞÛØàÝÚààÜÜÜØÞÛØÞÛØÞÛØÝÚ×ÝÚ×àÝÚÛØÕÜÙÖÞÛØÜÙÖÚ×ÔÚ×ÔÚ×ÔÛØÕÝÚ×Ú×ÔØÕÒØÕÒÛØÕÖÓÐØÕÒ×ÔÑØÕÒØÕÒÖÓÐØÕÒØÕÒ×ÔÑÕÒÏÖÓÐÓÐÍÕÒÏÕÓÍØÖÐÒÐÊÕÓÍÓÑËÔÒÌÒÐÊÒÐÊÒÐÊÒÐÊÒÐÊ423431542542542666777666666555444555555666>>>FFFNNNUUUYYYXXXXXXWWWXXXWWWXXXYYY[[[[[[\\\]]]^^^___aaaaaabbbcccddddddfffgfhhgijikihjihjjikjikkjljikkjlkjllkmkkokkollrkkqllrllrmltlksnlwnlwnlwpnyrp|sq}tqxuƒ}Ž—“¤¾·ÊÛÔçéáøüôÿþýÿýüþþýÿûúüöñþöñþóîüü÷ÿþüÿþüÿþüÿúøüûøÿýúÿüúþþüÿýûÿüúþöñþìçôõîý÷ðÿ÷ðÿôíüêâÿãÛøÏÄø¿´èÄ·ùÁ´öµªî¶«ïº­ï³¦è¯£é­¡ç¢—Û¢—Û¥›Ü®¤å³¨æ­¢à°©Ö³¬Ù«©»¥£µ££§¡¡¥žŸ¡š›œœ uuy“–Ž‘”ˆŠ‹“Ž–‘“™”•—˜ ™›¡œž¤ ¢¨¢¤ª©©­¬¬°¯¯³µµ¹¹º¼½¾ÀÀÁÃÄÅÇÈÈÈÌÌÌÎÎÎÑÑÑØØØÖÖÖÙÙÙÞÞÞàààâââäääæææèèèéééêêèëëéííëîîìðïíðïíñðîñðîòñïòñïòñïòñïñðîëêèËËË···µ¹º·»¼·»¼ÁÅÆððîòòðòñïñðîðïíïîìîíëíìêìëéìëéëêèìëéëêèíìêëêèìëéìëéëêèëêèêéçëêèëêèêéçêéçëêèêéçëêèêéçêéçêéçéèæéèæêéçèçåéèæèçåæåãèçåèçåèçåèçåçæäçæäçæäæåãæåãèåãçäâçäâçäâæãáæãáåâàåâàåâàãàÞäáßäáßåâàãàÞäáßãàÞâßÝãàÞãàÞãàÞâßÝãàÞáÞÜâßÝßÜÚáÞÜãàÞÞÛÙáÞÛÞÛØâßÜÞÛØßÜÙÜÙÖÞÛØÝÚ×ßÜÙÜÙÖàÝÚÚ×ÔÞÛØÜÙÖÛØÕÙÖÓÛØÕÙÖÓÛØÕÚ×ÔÛØÕÚ×ÔÚ×ÔÛØÕØÕÒÖÓÐ×ÔÑÙÖÓÕÒÏÛØÕÔÑÎÓÐÍÖÓÐÓÐÍÖÔÎ×ÕÏØÖÐÐÎÈÖÔÎÓÑËÔÒÌÒÐÊÖÔÎÎÌÆÓÑËÒÐÊÑÏÉ20121/21/431542444555333555555666777777555555444666:::AAALLLRRRXXXXXXXXXXXXXXXXXXXXXZZZ[[[\\\[[[]]]```___``````bbbdddedffeggfhgfhhgiihjihjjikjikjikkjlkjljjniimiiokkqkkqjjpkjrkjrljuljumkvmkvnlxomyqn|ro}so€vrƒ{t‡…~‘ž–­ËÃÚðïñüûýþýÿþýÿü÷ÿýøÿþùÿþùÿþüÿþüÿþüÿþüÿýúÿüùÿýûÿþüÿþüÿþüÿýøÿùôÿôíüõîýöïþòëúìäÿëãÿáÖÿÒÇûÌ¿ÿÕÈÿ·ûĹýÑÄÿÈ»ý÷ýÀ´ú¹®ò½²öº°ñµ«ì°¥ã¤™×¥žË®§Ô½»Í¸¶È¬¬°¡¡¥žŸ¡›œž››Ÿuuy‘”—’•‰‹‘‹“‘—’”š•–ž—˜ ™›¡Ÿ¥ ¢¨£¥«ªª®­­±°°´µµ¹¹º¼½¾ÀÁÂÄÃÄÆÈÈÈÌÌÌÐÐÐÓÓÓÕÕÕÖÖÖÚÚÚÞÞÞàààâââäääæææèèèéééêêèììêííëîîìïîìðïíñðîñðîñðîñðîñðîîíëÙØÖº¹·¶¶¶ººº¸¼½·»¼¸¼½´¸¹ããáññïòñïðïíîíëíìêéèæêéçèçåèçåèçåéèæéèæéèæéèæéèæêéçêéçéèæéèæëêèêéçéèæêéçêéçéèæêéçèçåéèæèçåéèæéèæéèæéèæêéçæåãèçåèçåçæäèçåèçåæåãæåãæåãåäâæåãèåãæãáçäâæãáçäâäáßåâàæãáäáßäáßäáßäáßäáßäáßãàÞãàÞãàÞãàÞãàÞãàÞâßÝáÞÜâßÝàÝÛßÜÚáÞÜâßÝÜÙ×àÝÚàÝÚÞÛØßÜÙàÝÚÝÚ×ÞÛØÝÚ×ÜÙÖáÞÛßÜÙÚ×ÔßÜÙÝÚ×ÛØÕÚ×ÔÛØÕÛØÕÝÚ×ÛØÕØÕÒÛØÕØÕÒØÕÒÖÓÐÖÓÐÕÒÏ×ÔÑÙÖÓØÕÒÓÐÍ×ÔÑ×ÔÑÓÐÍÕÓÍÖÔÎÒÐÊÒÐÊÖÔÎÑÏÉÓÑËÓÑËÖÔÎÎÌÆÓÑËÔÒÌÒÐÊ0/-10.21/320320312423423534423645756756756756666777777666777777???JJJPPPXXXXXXXXXXXXXXXWWWWWWYYYZZZ[[[[[[\\\]]]^^^```bbbddddcefegfeggfhgfhgfhhgiihjihjlkmkjljikiimjjniimiimjjpjjplkskjrlksmltljuljunlxnlxpm{qn|sp~tquq‚xt…†ƒ‘¥¢°ÏÍÙèæòóîûúõÿú÷ÿüùÿþþþþþþþþþüüüüûýúùûøöúýûÿþþþþþþþýÿø÷ùóìýðéúóëþðèûêàüçÝùçÛýåÙûÜÑþÐÅò½°ò¾±óÀ³õʽÿÏÄÿȽû¼°ö¹­óº®ô»¯õ¼¯ñ°£å¦™Ûµ¨ê»¯ïº®îº²æ¬¤ØŸ¯˜–¨–—¡rs}‘—Ž–ŠŒ’‹“’˜”–œ•——™Ÿšœ¢Ÿ¥ ¢¨£¥«©©­®®²±±µµµ¹¹¹½½½ÁÁÂÄÅÆÈÉÊÌÌÍÏÑÐÒÓÒÔÖÖÖÛÛÛÝÝÝÞÞÞàààâââäääæææèèèéééëëéììêííëííëïîìðïíðïíñðîñðîðïíääâÂÂÀ²³µµ¶¸µ¸»¶¹¼¶¹¼µ¸»¶¹¼¶¹¼ÁÃÃìîîðïíîíëìëéçæääãáäãáâáßãâàãâàåäâåäâåäâæåãæåãèçåèçåèçåèçåèçåéèæçæäèçåéèæéèæèçåéèæèçåéèæêéçéèæèçåéèæèçåçæäçæäæåãçæäçæäæåãæåãåäâæåãæåãæåãçäâçäâæãáæãáæãáåâàåâàåâàäáßäáßäáßãàÞåâàâßÝäáßâßÝäáßßÜÚäáßãàÞáÞÜáÞÜâßÝáÞÜàÝÛáÞÜáÞÜßÜÚáÞÛßÜÙÜÙÖãàÝÜÙÖÞÛØÝÚ×âßÜÝÚ×ßÜÙÛØÕÝÚ×ÝÚ×Ú×ÔÛØÕÙÖÓÚ×ÔÚ×ÔÙÖÓØÕÒÙÖÓÚ×ÔØÕÒÖÓÐ×ÔÑÕÒÏ×ÔÑÖÓÐ×ÔÑÔÑÎÕÒÏÔÑÎÕÒÏÓÐÍÔÒÌÕÓÍÓÑËÓÑËÖÔÎÏÍÇ×ÕÏÓÑËÔÒÌÎÌÆÓÑËÎÌÆÏÍÇ-,*-,*-,*/.,10.201201312312423312534645534645555666777777666666555555888<<>>HHHSSSYXZ\[][Z\ZY[[Z\ZY[ZY[[Z\]\^]\^_]a`^b`^ba_ca^ec`gbaidckedledlecnecnfdphfrhfrigsheshesgdrfcqhesifthgujiwjiwihvkjzihxjiylk{lk{lk{on~sr‚wu‡ƒ“›™«ÂÀÒäâíòðûðîúñïûøöÿöôÿçãûÞÚòáÚûäÝþÎÆðºäûìƾウ鯥ۯ¥à³©ä¯¥à²¨ã½²ð³¨æÁ·òÅ»ö´©ç½²ð¼±ïµªè¼²íº°ë±¦à¼±ë¼±ëº¯é¸±àº³â¸¸Ä»»ÇÂÂÆÆÆÊÉÊÌËÌÎÑÑÑÓÓÓ×××ÙÙÙÙÙÙÜÜÜÞÞÞ¼¼¼¤§ª¨«®¨¬²§«±©«±ª¬²ª¬²ª¬²«­³ª¬²«®±¬¯²«®±¬¯²­°³­°³­°³­°³¯²µ®±´®±´¯²µ°³¶¯²µ¯²µ°³¶±±µ°°´°°´¨¨¬žž¢žž¢žŸ¡›œžš›ž ¤¥§ª«­±±±µµµ¼º»Á¿ÀÂÁ¿ÇÆÄÉÈÆÍÌÊÎÍËÓÒÐÒÑÏÓÒÐÖÓÑØÕÓÛØÖÛØÖÜÙ×ÛØÖÝÚØÞÛÙÝÚØÛØÖÝÚØßÜÚáÞÜÞÛÙÝÚØßÜÚÞÛÙâßÝÞÛÙâßÝßÜÚàÝÛáÞÜâßÝáÞÜãàÞáÞÜàÝÛáÞÜáÞÜßÜÚáÞÜàÝÛâßÝàÝÛßÜÚàÝÛâßÝÞÛÙßÜÚßÜÚßÜÚáÞÜßÜÚÝÚØßÜÚÜÙ×àÝÛÝÚØÝÚØÜÙÖÝÚ×ÛØÕÝÚ×ÝÚ×ÜÙÖÜÙÖØÕÒÝÚ×ÛØÕÙÖÓØÕÒØÕÒÛØÕ×ÔÑÛØÕØÕÒØÕÒ×ÔÑØÕÒÙÖÓ×ÔÑÔÑÎÕÒÏÓÐÍÙÖÓÖÓÐÔÑÎÒÏÌÓÐÍÔÑÎÕÒÏÕÒÏÑÎËÒÐÊÔÒÌÎÌÆÕÓÍÍËÅÔÒÌÓÑËÑÏÉÐÎÈÕÓÍÑÏÉ756653653645534867534222333...)))$$$  ! #!"%#$%#$%#$)'()'(*()+)*,*+/-..,-/-.1/0201201423222333444333444555666666666777777888777777555666;:>>>>>>>>>>><<<<<<;;;:::::::::888666777666555645534534534534201---&&&!!! ###$$$'%&'%&'%&+)*+)*,*+.,-.,-/-.20120131242342344444444444466666665776887987976865754643598:@?AMLNUTV[Z\[Z\ZX\YW[XVZYW[ZX\\Z^]Za\Y`[[a\\b]\d_^f`_gbaia`hcbjdbmfdofdofdogeqgeqhfrgeqfdphfrifthesihvkjxlkymlzlkymlzmlzmlznm{nm{qp€wv†€”‘¥­©ÈÿÞÎÆñÏÇòÔËÿÑÈüÔÊÿÑÇýǽøÑÇÿ¾³ñ·¬ê»¯ï»¯ïµ÷µ÷»¯ï¾²òºӞ­£¢²©©¯¬¬²²²¸¶¶¼ºº¾¾¾ÂÁÂÄÄÅÇÇÇÇÈÈÈäääááᇉz|‚{}z|Žy{wy‹wy‹vxŠvxŠtvˆru…qt„~„¤ªµÊÑÚÎÕÞ¹ÀÅ¥¬±¢§ª§¬¯«®±©¬¯©¬¯ª­°ª­°­°³“–™¬¯² £¦•˜›¢¥¨¯²µ°°´¯¯³®¯±ª«­®¯±•–˜‡Š‰Œˆ‹Ž‰Œ‹‹‘““—ššž¡¢¤§¨ª®®®²²²·µ¶»¹º¿¾¼ÃÂÀÄÃÁÈÇÅËÈÆÏÌÊÏÌÊÒÏÍÒÏÍÒÏÍÒÏÍÖÓÑÕÒÐÕÒÐ×ÔÒÕÒÐÙÖÔÚ×ÕÚ×ÕÛØÖÛØÖÛØÖÜÙ×ÛØÖÝÚØÝÚØÞÛÙÝÚØÝÚØÞÛÙÝÚØÝÚØÞÛÙÞÛÙßÜÚßÜÚÜÙ×ÜÙ×ÝÚØÝÚØáÞÜÜÙ×ÝÚØÞÛÙÞÛÙÞÛÙÝÚØÝÚØÜÙ×ÞÛÙÜÙ×ÛØÖÝÚØÛØÖÛØÕÜÙÖÛØÕÜÙÖÛØÕÚ×ÔÚ×ÔÚ×ÔÙÖÓÙÖÓÜÙÖÚ×ÔÕÒÏÚ×ÔÛØÕ×ÔÑ×ÔÑØÕÒÖÓÐÕÒÏÕÒÏ×ÔÑÖÓÐØÕÒÓÐÍÔÑÎÔÑÎÑÎË×ÔÑÓÐÍÓÐÍÖÓÐÓÐÍÑÎËÑÏÉÔÒÌÏÍÇÖÔÎÍËÅÏÍÇÒÐÊÑÏÉÑÏÉÐÎÈÍËÅ???>>>??????>>>???>>><<<<<<;;;:::::::::999888867756756534645534444333333...)))'''!!! #!"%#$$"#&$%'%&'%&*(),*+,*+.,-/-./-.1/0201000444333222333666657546546768657768879657657768546768>=?GFHRPTYW[ZX\ZX\YW[YW[YV]ZW^VV\XX^YX`YX`[Zb\[c]\d`_ga_jdbmcaldbmdbndbndbndbngeqfdpgdrgdrfesgftihvjiwjiwjiwlkymlzlkyon|nm}nm}po„qp…tp{š’Šµ®¦ÑżðÎÅùÌÂøÉ¿õǽøÊÀû·õ¹®ì½±ñÁµõµ÷Ä·ùÀ´ô¶ªêƒ{¯…¹¤£³©¨¸®®´°°¶³³¹µµ»ºº¾½½ÁÁÂÄÁÂÄÈÈÈíííÍÍÍ|||y{|~„xzŒxzŒuw‰tvˆtvˆsu‡tvˆtvˆsv†ru…qw‚ntls||ƒŒ¤«°ÌÓØÏÔ׸½À©¬¯¥¨«¨«®ª­°ª­°«®± £Ÿ¢¥®±´­°³¥¨«š ¡¡¥ªª®«¬®ª«­«¬®£¤¦ƒ†‰ˆ‹Ž†‰Œ…ˆ‹ˆˆŒ‰‰‘’’–š›¡¢¤©©©¬¬¬²°±·µ¶»º¸¿¾¼ÂÁ¿ÄÃÁÉÆÄÉÆÄÍÊÈÍÊÈÐÍËÐÍËÐÍËÑÎÌÒÏÍÒÏÍÕÒÐÔÑÏ×ÔÒ×ÔÒØÕÓÚ×ÕÚ×ÕÚ×ÕÜÙ×ØÕÓÜÙ×ÛØÖÛØÖÚ×ÕÜÙ×ÝÚØÛØÖÝÚØÝÚØÜÙ×àÝÛÜÙ×ÝÚØÜÙ×Ú×ÕÜÙ×ßÜÚÚ×ÕÜÙ×ÜÙ×àÝÛÜÙ×ÞÛÙÜÙ×ÝÚØÝÚØÛØÖÜÙ×Ú×ÕÜÙ×ÛØÕÙÖÓÛØÕÜÙÖÛØÕÚ×ÔÙÖÓÚ×ÔÙÖÓÚ×ÔØÕÒÚ×Ô×ÔÑ×ÔÑÖÓÐÚ×Ô×ÔÑÖÓÐ×ÔÑÓÐÍÙÖÓÖÓÐÕÒÏÔÑÎÒÏÌÕÒÏÕÒÏÓÐÍÖÓÐÒÏÌÔÑÎÓÐÍÒÏÌÒÏÌÕÓÍÏÍÇÐÎÈÏÍÇÒÐÊÎÌÆÒÐÊÐÎÈÏÍÇÑÏÉÍËÅ??=>><>><>>>???@@@>>>===???>>>======>>>===;;;;;;999888888888777555666645645645534423201***$$$  !!!"""%%%$$$&&&'''+)*,*+,*+/-./-.2011/01/0312534423423414636546546768657768768546768657435546:9;CBDMLNXVZ[Y]ZX\XVZWUYYW[XU\XU\XX^YY_ZZ`[[a]\d^]e_^f`_gbaia`hb`kcalecngepfdofdoeeqeeqffrggsiiuggsiiujjvkkwllxnnznnzpp|pp|po}tsxw‡{zŠ…„š™˜®ª¤Ï¼¶áǽøÉ¿úƽüżûƽüÄ»úÊÁøżó¼ÛICb""&&&*679XY[}~€žŸ¡³´¶¼½¿ÀÁÃÀÁü¾¾ÈÊÊððð±±±st|{|„wzŠuxˆtvˆtvˆqs…rt†qs…pr„pt…os„os„os„pt…rv‡rv‡rv‡ns‚lq€w}ˆž¤¯ÄËÒÆÍÔ¯³¹¦ª°©¬¯©¬¯«®±‰Œ¬¯²¨«®§ª­©¬¯««¯¦¦ª§¨ª¨©«¨©««¬®‡‹Œ…†‚…ˆƒ†‰ƒ†‰„‡Š†‰Œ‹Ž‘••™››Ÿ¤£¥¨§©®¬­²°±·¶´»º¸Â¿½ÄÁ¿ÅÂÀÇÄÂËÈÆÌÉÇÌÉÇÌÉÇÎËÉÐÍËÏÌÊÓÐÎÔÑÏÔÑÏÕÒÐÕÒÐ×ÔÒÙÖÔØÕÓÚ×ÕÙÖÔÙÖÔÚ×ÕÛØÖÝÚØÙÖÔÛØÖÜÙ×ÝÚØÝÚØÜÙ×ÛØÖÞÛØÝÚ×ÝÚ×ÝÚ×ÝÚ×ÜÙÖÞÛØÜÙÖÜÙ×ÛØÖÜÙ×ÛØÖÜÙ×ÝÚØÞÛÙÚ×ÕÛØÖÞÛÙÙÖÓÜÙÖÜÙÖÚ×ÔÛØÕÝÚ×ØÕÒÙÖÓ×ÔÑÛØÕÙÖÓÚ×ÔØÕÒØÕÒØÕÒÖÓÐ×ÔÑÙÖÓØÕÒÕÒÏÔÑÎÔÑÎØÕÒÒÏÌÕÒÏÕÒÏÓÐÍÕÒÏÓÐÍÔÑÎÓÐÍÕÒÏÓÐÍÏÌÉÖÓÐÓÐÍÏÍÇÐÎÈÐÎÈÒÐÊÑÏÉÐÎÈÐÎÈÐÎÈÎÌÆÓÑËÐÎÈ??=@@>>><>>>>>>@@@@@@>>>??????>>>??????>>>>>>???===<<<;;;;;;:::999999867756756867867645777555333111,,,$$$  """###%#$'%&(&')'(,*+-+,-+,.,-0./312201312303414435324546657546546657657768768768768546324759?=AIGKUSWZX\[Y]ZW^WT[UU[UU[UU[WW]XW_XW_ZYa\[c]\d_^f^\ga_ja_jecndbmdbmddpddpddpeeqggsffrggsggsiiujjvkkwkkwmmynnzon|rqsr‚sr‚utŠyxŽ|v¡‚|§…À©ŸÚ¾µôǾýÈ¿þÈ¿þßÖÿª¡Ø­§Æ+$D&&*''+%&(#$&"#%"#%./1MNPyz|ž ÀÂÂéëë”””www|}…{|„sv†qt„pr„oqƒoqƒnp‚np‚np‚ko€mq‚lplpmq‚os„pt…rv‡tyˆsx‡qw‚ntlszx†§«±¨¬²ª­°­°³®±´‡Š©¬¯¨«®¥¨«¦©¬¦¦ª§§«¦§©¦§©¥¦¨¨©«˜œ{€€ƒ†€ƒ†„‡„‡„‡Šˆ‹Ž‘••™œž£¢¤ª¨©°®¯³²°·¶´½º¸¾»¹Á¾¼Â¿½ÇÄÂÈÅÃÇÄÂÉÆÄËÈÆÎËÉÍÊÈÒÏÍÐÍËÓÐÎÓÐÎÔÑÏØÕÓÖÓÑØÕÓØÕÓØÕÓØÕÓÙÖÔÚ×ÕÛØÖÚ×ÕÛØÖÚ×ÕÛØÖÚ×ÕÚ×ÕÛØÖÞÛØÚ×ÔÝÚ×ÝÚ×ÛØÕÛØÕÞÛØÚ×ÔÛØÖÚ×ÕÙÖÔßÜÚÙÖÔÞÛÙÛØÖÜÙ×Ú×ÕÞÛÙØÕÒßÜÙÚ×ÔÛØÕØÕÒÙÖÓÖÓÐØÕÒÚ×ÔÜÙÖ×ÔÑÙÖÓÖÓÐØÕÒØÕÒ×ÔÑÕÒÏ×ÔÑØÕÒÔÑÎ×ÔÑÖÓÐÔÑÎÔÑÎÔÑÎÕÒÏÑÎËÓÐÍÒÏÌÖÓÐÒÏÌÓÐÍÒÏÌÐÍÊÕÒÏÑÎËÑÏÉÓÑËÏÍÇÑÏÉÐÎÈÎÌÆÑÏÉÐÎÈÎÌÆÐÎÈÍËÅ@@>>><>>>>???AAAAAA@@@???@@@??????@@@@@@@@@@@@@@@??????>>>;;;:::;;;999777777888777666555555666111111,,,$$$  """###$$$%%%)'(+)*+)*-+,.,-0./1.12/2303303213324435435546657546657657657657657546435324324:9;FEGPNRVTXXVZWUYVTXVTXWT[WT[WT[YV]XX^YY_ZZ`[[a]\d^]ea`hbaibaicbjdbmfdoefpfgqghrfgqghrghriiuhhtiiummyllxoo{oo{ssssuuzz†{{‡{|Œ}~Žƒ€›–“®°¬ËÙÕôïíø©§²¦¤¨)'+'''((((&')'())))))'''%%%"""###///666<=?bceqr|yz„wy†tvƒpsƒnqkmkmkmln€jnjnjnjnlpnrƒnrƒmq‚kq‚nt…ms„nt…ms„kq‚mrotty„€…—¤Ž”›ž¢©¤¨¯¥¨«£¦©¥¦¨£¤¦£¤¦¢£¥¡¢¤¡¢¤¥¦¨…†ˆ}€ƒ‚…‚…‚…ˆƒ†‰ƒ†‰†‰Œ‹Ž‘•–˜›œž¢¢¢¨¨¨®­«´³±¶µ³¹¸¶¾»¹Á¾¼ÄÁ¿ÄÁ¿ÆÃÁÈÅÃÊÇÅËÈÆËÈÆÎËÉÏÌÉÐÍÊÒÏÌÖÓÐÔÑÎÓÐÍÖÓÑÖÓÑÙÖÔÕÒÐØÕÒÚ×ÔÚ×ÔØÕÒÜÙÖÙÖÓÙÖÓÚ×ÔÛØÕÚ×ÔÛØÕÛØÕÛØÕÛØÕÝÚ×ÝÚ×Ú×ÔÛØÕÛØÕÚ×ÔÛØÕ×ÔÑÛØÖÚ×ÕÚ×ÕÜÙ×ÛØÖÚ×ÕÙÖÓÞÛØØÕÒÜÙÖÚ×ÔÙÖÓ×ÔÑÜÙÖÚ×ÔÙÖÓØÕÒÖÓÐÚ×ÔØÕÒÙÖÓÕÒÏÕÒÏØÕÒ×ÔÑÓÐÍÖÓÐÖÓÐÖÓÐÔÑÎÔÑÎÕÒÏÑÎËÖÓÐÓÐÍ×ÔÑÏÌÉÕÒÏÑÎËÑÎËÑÎËÑÎËÑÏÉÒÐÊÑÏÉÎÌÆÍËÅÓÑËÓÑËÍËÅÐÎÈÎÌÆÌÊÄ@@>??=@@>@@@@@@@@@>>>>>>AAAAAAAAA@@@AAAAAA@@@???@@@AAAAAA@@@???AAA@@@@@@???>>>===;;;;;;999999999999777666666555555555333...((($$$  !!!$"#%#$&$%(&')'(-+,,),,),-*-0-0/.00/11020/121321332443554643554654654654643554632432431586:B@DKIMUSWXVZYV]VSZVSZVSZSSYUU[UU[VV\YX`YX`\[c]\d]\d^]e`^ia_jablbcmdeodeofgqfgqffrffrggshhtiiukkwllxmmyoo{oo{ssvv‚vw‡yzŠzw’|y”{š†‚¡ ž©§¥°¢ ¤759######'%&(&'&&&&&&&&&&&&'''''''''&&&"#% !# *()38:GPR__brkn~oqƒmojl~hj|gk|gk|gk|hl}hl}im~jnim~gm~fl}hnio€io€jpns€pu‚sxƒrw‚nt{mszy}„‘˜¢¥¨¨«®¨©«¦§©¤¥§¢£¥¡¢¤ ¡£¡¢¤•–˜wz}z}€}€ƒ}€ƒ|‚|‚€ƒ††‰ŒŽ‘•–˜žžž£££©¨¦­¬ª±°®´³±»¸¶»¸¶À½»Á¾¼ÄÁ¿ÆÃÁÇÄÂÈÅÃËÈÆÌÉÇÍÊÇÌÉÆÐÍÊÐÍÊÒÏÌÓÐÍÓÐÎÔÑÏÕÒÐÕÒÐØÕÒÖÓÐÚ×ÔÖÓÐØÕÒ×ÔÑÙÖÓÛØÕÚ×ÔØÕÒÛØÕØÕÒØÕÒÜÙÖÚ×ÔÞÛØÛØÕÙÖÓÚ×ÔÙÖÓÚ×ÔÛØÕØÕÓØÕÓÚ×ÕØÕÓÛØÖÙÖÔÙÖÓÚ×ÔÙÖÓ×ÔÑÙÖÓÙÖÓÕÒÏØÕÒØÕÒÖÓÐ×ÔÑÖÓÐÛØÕÕÒÏÖÓÐÔÑÎØÕÒØÕÒÓÐÍ×ÔÑÕÒÏÕÒÏ×ÔÑÐÍÊÐÍÊÖÓÐÔÑÎÔÑÎÑÎËÒÏÌÏÌÉÓÐÍÒÏÌÓÐÍÎËÈÕÒÏÐÎÈÒÐÊÓÑËÌÊÄÑÏÉÑÏÉÏÍÇÏÍÇÐÎÈÍËÅÍËÅ@@>@@@AAA@@@AAAAAA@@@AAAAAAAAABBB@@@???AAAAAA@@@???@@@AAAAAA@@@AAAAAAAAAAAABBBAAA@@@???>>>???;;;;;;;;;;;;999777666666555777978756333///(((### !!!!!!"""$$$&&&((()))+++-+,.,-/////////111111111213102324435435324435546435435546435435324546<;=EDFQPRVTXWUYUSWVTXVTXUSWVV\VV\VV\WW]XX^ZZ`\\b\\b^]e_^fa`hdckfemhgoefpfgqfgqghrghrhishisjkuklvmnxnoyqr|qr|vwuv~vw{|„|}…ƒƒ‰ŒŒ’  ¦¦¦¬ŒŒZZ^102"!#"""%%%'%&%#$'%&&$%'&$'&$&%#&%#$$"%%####!!!! "'&(55;EEKX[egjtlnzmo{imzhlyejyejydixchwchwchwfkzfkzgl{hm|in}in}jo|kp}jp{jp{hnyekvgmtv|ƒ’•˜£¦©©ª¬¦§©¢£¥¢£¥ ¡£¡¢¤ux{wz}x{~y|z}€{~}€ƒ„‡†‰Œ“•——œžž£££¨¨¨¬«©°¯­³²°·¶´¼¹·½º¸Á¾¼ÃÀ¾ÅÂÀÇÄÂÇÄÁËÈÅËÈÅÍÊÇÍÊÇÐÍÊÎËÈÒÏÌÓÐÍÓÐÍÔÑÎÕÒÏÖÓÐØÕÒÖÓÐÖÓÐÙÖÓØÕÒØÕÒÚ×ÔÖÓÐÚ×ÔÛØÕØÕÒÙÖÓÜÙÖØÕÒÙÖÓØÕÒÛØÕÚ×ÔÙÖÓØÕÒØÕÒ×ÔÑØÕÒØÕÒØÕÒÛØÕÛØÕØÕÒÚ×ÔÙÖÓ×ÔÑÙÖÓØÕÒÖÓÐØÕÒÚ×Ô×ÔÑÖÓÐÕÒÏÚ×ÔÔÑÎ×ÔÑÕÒÏ×ÔÑÖÓÐÔÑÎÔÑÎÔÑÎÓÐÍÓÐÍÑÎËÑÎËÖÓÐÓÐÍÖÓÐÑÎËÑÎËÏÌÉÒÏÌÔÑÎÐÍÊÑÎËÐÍÊÏÍÇÐÎÈÑÏÉÑÏÉÎÌÆÎÌÆÐÎÈÓÑËËÉÃÏÍÇÌÊÄ@@>@@@???@@@AAA@@@AAABBBBBBAAA@@@@@@AAABBB@@@BBBBBBAAAAAAAAAAAADDDBBBBBBBBBBBBBBBBBBAAABBBAAA???>>>>>>======;;;:::999999888978978777777777444333...'''"""!!!###$$$%%%(&'*()***+++,,,---///0000/1/.00/1102213213213213324324435435324435657324213102648?=ALJNUSWWUYVTXSSYRRXRRXSSYSSYTTZVV\XX^YX`[Zb]\d^]e`_gcbjcdndeodeoefpghrghrghrghrijtjkujkulmwnoyqr|opxqrzrs{tu}zz€{{||‚ƒƒ‰”¡¡¥¨§©ŒŽYYY///" !" !%#$&$%&%#%$"$#!%$"$$"##!######$#%#"$ &%( *')58:FLP]^bochwfkzdixbgv`et_ds`etafubgvafuafu`etafsdivcitekvekvdjucip^dk`cfehk|}–—™¥¦¨£¤¦¡¢¤¤¥§‚…ˆruxux{wz}y|y|y||‚€ƒ††‰Œ‘‘—™™¢¢¢©¨¦¬«©¯®¬³²°¸µ³»¸¶¿¼ºÂ¿½ÃÀ¾ÅÂÀÆÃÀÈÅÂÊÇÄËÈÅÌÉÆÎËÈÌÉÆÐÍÊÐÍÊÓÐÍÐÍÊÔÑÎÔÑÎÓÐÍÕÒÏÕÒÏ×ÔÑÕÒÏ×ÔÑØÕÒ×ÔÑÚ×Ô×ÔÑØÕÒÙÖÓØÕÒØÕÒØÕÒÙÖÓÚ×ÔÛØÕÚ×ÔÖÓÐÙÖÓØÕÒÚ×ÔÖÓÐÖÓÐØÕÒÙÖÓ×ÔÑÙÖÓ×ÔÑ×ÔÑ×ÔÑØÕÒÖÓÐÕÒÏØÕÒÚ×ÔÔÑÎÖÓÐÙÖÓÖÓÐÖÓÐÕÒÏ×ÔÑÔÑÎÕÒÏÕÒÏÕÒÏÔÑÎÒÏÌÕÒÏÒÏÌÖÓÐÔÑÎÓÐÍÒÏÌÓÐÍÑÎËÑÎËÔÑÎÑÎËÎËÈÏÌÉÒÐÊÑÏÉÓÑËÏÍÇÎÌÆÏÍÇÑÏÉÊÈÂÏÍÇÍËÅÏÍÇ@@>BBBBBBAAAAAA@@@@@@BBBBBB@@@AAACCCBBBBBBBBB@@@CCCBBBBBBAAACCCDDDBBBCCCCCCCCCDDDCCCCCCCCCCCCBBBAAACCC@@@AAA@@@???======;;;999888888888777777777555777666000,,,'''!!!!!!!!!$$$###&&&((()))***+++---.........0000000/1102102102102102213324213435435435435213102435=<>GFHPOQUTVTTXQQURRVRRVRRVSSWUUYVVZXX^YY_[[a\\b__eaag`bhbdjefndemdemefnghphiqhiqijrijrkltlmumnvqqwqqwttzvv|xx|yy}zz~}}€ƒ†Ž‘”¤¥§¦§©‰‹‹SUU,,, !!##!%$"%$"$#!$#!$#!#" #" #" $#!$#!%$"$#!"""!!! $$(226BDJUW]_blbeoafq_doW\iV[hY^kX]j_dq]bo^cn`epbgq^cm_cj`dk]ag[_e[^a]`cjnoƒ‡ˆ™ž¢¦§™žostruxtwzvy|wz}vy|x{~z}€€ƒ†‰ŠŒ’———ŸŸŸ¥¤¢§¦¤¬«©®­«µ²°·´²»¸µ½º·À½ºÁ¾»ÃÀ½Å¿ÈÅÂÉÆÃÉÆÃÌÉÆÍÊÇÏÌÉÍÊÇÐÍÊÍÊÇÐÍÊÒÏÌÒÏÌÒÏÌÑÎËÔÑÎÕÒÏ×ÔÑÔÑÎ×ÔÑ×ÔÑÖÓÐØÕÒØÕÒ×ÔÑÛØÕØÕÒ×ÔÑ×ÔÑØÕÒÙÖÓ×ÔÑÖÓÐÖÓÐ×ÔÑÓÐÍØÕÒ×ÔÑ×ÔÑÕÒÏ×ÔÑÖÓÐÖÓÐÖÓÐÖÓÐÕÒÏÔÑÎÕÒÏÖÓÐÕÒÏÕÒÏÕÒÏÙÖÓÓÐÍÕÒÏÔÑÎÓÐÍÕÒÏÓÐÍÕÒÏÔÑÎÓÐÍÓÐÍÓÐÍÑÎËÐÍÊÒÏÌÒÏÌÎËÈÑÎËÐÍÊÔÑÎÍÊÇÏÌÉÏÌÉÓÑËÐÎÈÑÏÉÍËÅÒÐÊÎÌÆÏÍÇÉÇÁÓÑËÌÊÄÏÍÇ??=AAAAAA@@@AAAAAABBBAAABBBAAABBBBBBAAACCCBBBAAAAAACCCCCCCCCCCCBBBBBBEEEDDDDDDCCCCCCCCCDDDDDDCCCBBBCCCDDDBBBAAAAAAAAABBB@@@>>><<<<<<===::::::888777777888777666666444111+++&&&!!! !!!"""$$$&&&'''))))))---------.-/.-//.00/10/11021021021022132132133243243244352130/10/1879BBFMMQRRVTTXSSWQQUPPTRRVSSYTTZUU[VV\WW][[aZ\b\^d_`habjabjcdldemghphiqhiqijrijrijrlmunntnntnntqqwsswuuyvvzxx|wz}x{~}~€„…‡’””£¥¥¨¨¨†††OOM((&! #" #" $#!$#!#" "!"!"!"!$#!"""######### $ $%#)&)35:E:?JŠœ‡Œ™gly_dqƒˆ•UZgW\gjozdisW\fY]dsw~Z^d[_erux[^aW[\[_`\`alpqŠŽquvorupsvruxtwztwzux{wz}|‚„…‡Š‹’’’™™™Ÿžœ¢¡Ÿ¨§¥ª©§±®¬³°®·´±»¸µ½º·¿¼¹À½ºÃÀ½ÄÁ¾Å¿ÈÅÂÊÇÄÌÉÆÌÉÆÍÊÇÌÉÆÍÊÇÐÍÊÑÎËÏÌÉÒÏÌÒÏÌÔÑÎÓÐÍÔÑÎÕÒÏÖÓÐÖÓÐÖÓÐ×ÔÑ×ÔÑØÕÒ×ÔÑÖÓÐ×ÔÑØÕÒØÕÒ×ÔÑØÕÒ×ÔÑÖÓÐÕÒÏÔÑÎÖÓÐ×ÔÑÕÒÏÔÑÎÕÒÏ×ÔÑÕÒÏ×ÔÑÔÑÎÖÓÐÔÑÎ×ÔÑÕÒÏÖÓÐÔÑÎÕÒÏÕÒÏÓÐÍ×ÔÑÓÐÍÓÐÍ×ÔÑÑÎËÔÑÎÔÑÎÖÓÐÑÎËÑÎËÕÒÏÓÐÍÔÑÎÒÏÌÏÌÉÑÎËÑÎËÐÍÊÑÎËÓÐÍÏÌÉÐÎÈÐÎÈÑÏÉËÉÃÓÑËÌÊÄËÉÃÐÎÈÎÌÆÍËÅÎÌÆAA?AAAAAAAAABBBBBBBBBBBBBBBCCCCCCBBBAAADDDAAAAAAAAABBBAAABBBDDDCCCBBBCCCDDDDDDDDDDDDDDDDDDDDDCCCCCCCCCEEEDDDCCCDCECBDDDDDDDBBBBBBA@B@?A>=?=<>=<><;=;:<:9;:::888657657858969657546222...'''!!! ###$$$&&&'''((()))+++,,,,,,.-/.-//.0/.0/.0/.00/12133241022132132134354351020/1/.0102=<>KJLQPRRRVSSWQQUPPTRRVRRVRRVSSWVV\WW]ZZ`\\b]]c^^d_agbdjfhnfhngiogiojjpkkqllpkkokkommqoosqqusswrrvstvuvxvwyyz|{|~}~€„††”––¦¨¨¥§§~~HKH&&$ ##!$#!"!"!#" "!#" "!#" $#!$#!#" #" $#!$#!"" "" """%&(+,.@DJW[adhoY]dW[ajntY]dPT[VZ`koubfljntˆŒ¥©ª·¹¹œžžvxxfhhdgjlorlormpsoruqtwruxsvysvywz}~ƒ„†‰ŠŒ’“•———žžž¤£¡¦¥£«ª¨¯®¬´±¯µ²°º·´¼¹¶¾»¸Á¾»ÃÀ½Å¿ÇÄÁÇÄÁÊÇÄÉÆÃËÈÅËÈÅÌÉÆÐÍÊÍÊÇÒÏÌÑÎËÏÌÉÑÎËÎËÈÔÑÎÓÐÍÒÏÌÔÑÎÕÒÏ×ÔÑÕÒÏÕÒÏÖÓÐÕÒÏØÕÒÖÓÐÔÑÎ×ÔÑØÕÒ×ÔÑÚ×ÔØÕÒÕÒÏÓÐÍÓÐÍÓÐÍÔÑÎÔÑÎÒÏÌÔÑÎÖÓÐÒÏÌÖÓÐÓÐÍÕÒÏÖÓÐÒÏÌÕÒÏ×ÔÑÕÒÏÔÑÎÔÑÎÓÐÍÔÑÎÓÐÍÑÎËÓÐÍÒÏÌÒÏÌÐÍÊÒÏÌÒÏÌÑÎËÑÎËÏÌÉÎËÈÑÎËÒÏÌÌÉÆÓÐÍÐÍÊÑÎËÎÌÆÏÍÇÌÊÄÍËÅÓÑËÏÍÇÌÊÄÐÎÈÎÌÆËÉÃÎÌÆ00.555888<<=?===<<<;:<98:969858879768777777666555111---&&& """###$$$%%%((()))*)+*)+,+--,.-,.-,..-/.-//.0/.0/.00/10/12131021021022132130/1.-//.099=CCGMMQRRVQQUPPTPPTOOSPPVRRXSSYTTZVV\WW]XZ`Y[a]_e`bhbdjcekggmhhnkkojjnjjnkkokkommqnnroosqrtqrtstvuvxwxzwxzxzzz||}†ˆˆ•˜•¥¨¥¥¥£||zCCA"" ! #" $#!#" #" #" #" "!#" #" #" #" $#!##!"" ######!"$!"$%$%!(&*0@DJBFMMQXVZ`nrxnrxrv|‡‹Œ¥©ªª¬¬ÀÂÂãåå–˜˜lorjmpjmpknqmpspsvoruqtwqtwsvyyz|~„…‡Œ’’’˜˜˜ Ÿ£¢ ¦¥£«ª¨°­«´±¯¶³°¹¶³¼¹¶½º·À½ºÃÀ½Å¿Å¿ÆÃÀÇÄÁËÈÅËÈÅÊÇÄÌÉÆÍÊÇÍÊÇÎËÈÏÌÉÏÌÉÐÍÊÓÐÍÒÏÌÓÐÍÖÓÐÔÑÎÓÐÍÒÏÌ×ÔÑÓÐÍÔÑÎØÕÒÕÒÏÖÓÐ×ÔÑÖÓÐ×ÔÑÕÒÏÕÒÏÕÒÏÔÑÎÓÐÍÔÑÎÑÎËÔÑÎÔÑÎÒÏÌÐÍÊÒÏÌÔÑÎÔÑÎÒÏÌÖÓÐÓÐÍÔÑÎÖÓÐÓÐÍÑÎËÓÐÍÕÒÏÒÏÌÒÏÌÒÏÌÒÏÌÔÑÎÑÎËÏÌÉÑÎËÑÎËÏÌÉÒÏÌÏÌÉÐÍÊÐÍÊÐÍÊÒÏÌÏÌÉÎËÈÏÌÉÍËÅÐÎÈÐÎÈÎÌÆÐÎÈÍËÅÐÎÈÎÌÆÎÌÆÍËÅÍËÅ997442220000222333666;;;>>>BBBBBBCCCCCCBBBCCCCCCBBBCCCCCCDDDDDDDDDDDDCCCCCCDDDEEEFFFDDDDDDEEEDDDFFFFFFDDDCCCCCCDDDEEEDDDFFFCCCFFFDCEDCEDCECBDEDFCBDBACCBDBAC@?A?>@>=?<;=<;=:9;879:9;879657768879768768324333,,,$$$ !!!"""###&&&'''(((******++++++....../.0.-/.-//.0/.0/.0/.01021020/10/11020/1/.0-.0235<=?GHJQQUQQUQQUOOSNNROOSOOSQQUTTXUUYVVZZZ^\\`]]aaaeccgddhffjhhliimjkmklnlmolmolmolmonoqoprrsuuvxwxzuvxvxxwyyz||}†ˆˆ˜šš¨«¨¡¤¡vvt@@>""  !!#" "!"!"!#" #" "!#" $#!#" "!#" $#!%$"%$"#" %$"$#!##!!! !!(((<<@>=?>=?<;=98:98:879768768768777666777555111***$$$ !!!$$$$$$'''))))))***,+-,+--,.-,..-//.0/.0/.0.-/.-//.00/10/1/.0-.0-.0-.0+,.//399=EEINNRQQUPPTOOSPPTRRVRRVTTXSSWTTXWW[XX\[[_]]aaaebbfddhghjjkmklnlmoklnmnplmomnpmnpoprqrtrsusuutvvuwwvxxxzzy{{~~‡Š‡šš˜©©§ŸŸoom::8!!! ! "!"!#" "!"!$#!#" "!#" #" $#!#" #" #" #" ##!##!##!$$"###""""""###)++355UUS¥¥£ƒ„€Œ‰gklcghfilgjmgjmjmpknqmpsmpsnqtrsuvwy|}€‚ˆˆˆŽŽŽ•“”š˜™¡ ž¥¤¢¨¥£¬©§°­«²¯­·´±¹¶³¼¹¶¿¼¹¿¼¹Â¿¼Â¿¼ÄÁ¾ÉÄÁÇ¿ÉÄÁÉÄÁÊÇÄÊÇÄÍÊÇËÈÅÌÉÆÍÊÇÎËÈÎËÈÐÍÊÎËÈÑÎËÒÏÌÐÍÊÑÎËÓÐÍÓÐÍÓÐÍÓÐÍÓÐÍÓÐÍÔÑÎÓÐÍÖÓÐÕÒÏÔÑÎÓÐÍÔÑÎÒÏÌÕÒÏÓÐÍÐÍÊÐÍÊÑÎËÒÏÌÑÎËÑÎËÐÍÊÓÐÍÒÏÌÓÐÍÑÎËÓÐÍÒÏÌÓÐÍÔÑÎÑÎËÑÎËÒÏÌÓÐÍÏÌÉÐÍÊÔÑÎÓÐÍÐÍÊÎËÈÓÐÍÍÊÇÐÍÊÌÉÆÓÐÍÎËÈÒÏÌÑÎËÍÊÇÌÊÄÏÍÇÌÊÄÎÌÆÎÌÆÎÌÆËÉÃËÉÃÏÍÇÏÍÇÊÈÂCCCEEEEEEEEEFFFHHHHHHEEE@@@;;;777222111111222666;;;???BBBCCCDDDDDDDDDDDDDDDDDDDDDDDDFFFGGGFFFFFFFFFFFFGGGFFFEEEEEEFFFEEEDDDGGGDDDFFFFFFGGGFFFFFFHHHFEGFEGEDFFEGEDFCBDEDFDCEBACBACA@BBAC@?A@?A=<>;:<98:87998:879768879657657666444000)))### """$$$&&&&&&((())))))+++,,,-------------,.-,..-//.00/1/.01021020/10/1+,.+,.235>?AMNPPQSQQUQQUPQSPQSPQSRSUQRTTUWVWYXY[[\^[\^^_acdfefhghjijljkmklnklnjkmklnmoonppnppqssqsssuutvvvxxwyyy{{{}}~€€†ˆˆ™››¨«¨ššmmk997  $#!#" #" #" #" #" #" #" $#!$#!#" #" #" #" $#!#" $#!$#!$#!%$"&%#('%%$">><§§¥tvv…‡‡cgh`de`cfcfiehkgjmjmpknqlormpspqsstvwxz|}‚ƒ…ˆ‰‹ŽŽŽ”””š™— Ÿ¦£¡©¦¤¬©§¯¬ª³°­µ²¯¸µ²¹¶³¾¹¶Á¼¹Ã¾»Ä¿¼ÅÀ½ÆÁ¾ÉÄÁÊÅÂÊÅÂÌÇÄÍÈÅÌÇÄÍÈÅÎÉÆÍÈÅÏÊÇÏÊÇÑÌÉÒÍÊÒÍÊÑÌÉÓÎËÔÏÌÓÎËÓÎËÕÐÍÒÏÌÒÏÌÕÒÏÔÑÎÔÑÎÔÑÎÒÏÌÔÑÎÒÏÌÒÏÌÒÏÌÒÏÌÑÎËÑÎËÑÎËÐÍÊÏÌÉÏÌÉÏÌÉÐÍÊÑÎËÒÏÌÒÏÌÓÐÍÒÏÌÏÌÉÐÍÊÑÎËÐÍÊÑÎËÑÎËÑÎËÏÌÉÒÏÌÍÊÇÐÍÊÏÌÉÏÌÉÎËÈÐÍÊÑÎËÐÍÊÏÌÉÎËÈÎÌÆÍËÅÎÌÆÐÎÈÌÊÄÌÊÄÐÎÈËÉÃÍËÅÌÊÄÍËÅËÉÃÎÌÆCCCFFFFFFDDDEEEFFFFFFGGGHHHGGGIIIIIIFFFBBB:::555222111222666:::@@@CCCDDDCCCCCCDDDCCCCCCDDDFFFFFFFFFFFFFFFEEEEEEFFFFFFFFFHHHEEEHHHGGGFFFFFFFFFGGGHHHFEGFEGEDFGFHGFHEDFEDFGFHEDFDCEEDFDCEDCECBDA@BA@B?>@>=?<;=;:<:9;98:879657666666888666333333---(((!!! """$$$%%%&&&((()))***++++++,+--,.,+--,..-/-,./.00/1/.0102./1./1,-/+,.-.0124<<@GGKOPRQRTRSUOPRNOQOPRQRTRSUTUWTUWUVXXY[[\^`acdegdegfgighjhikjkmkmmkmmlnnmoomoooqqqssrtttvvvxxwyyxzzy{{z||‚‰Œ‰››™©©§šš˜iig542! #" #" #" "!"!#" $#!"!#" #" #" #" #" #" $#!%$"%$"&%#'&$%$"BB@¯¯­mooƒ……aef^bc_beadgcfidgjgjmjmpjmpjmpnoqpqsstvwxz}~€‚ƒ…ŒŒŒ—–”œ›™¡žœ¥¢ ©¦¤®«©°­ª²¯¬¶³°·´±»¶³¿º·¿º·Á¼¹Ã¾»Ä¿¼Ç¿ÆÁ¾ÈÃÀÉÄÁÊÅÂËÆÃÌÇÄÎÉÆÎÉÆÏÊÇÏÊÇÐËÈÐËÈÒÍÊÐËÈÖÑÎÒÍÊÑÌÉÔÏÌÔÏÌÒÏÌÑÎËÒÏÌÑÎËÑÎËÐÍÊÒÏÌÔÑÎÑÎËÒÏÌÒÏÌÔÑÎÑÎËÒÏÌÑÎËÍÊÇÍÊÇÎËÈÍÊÇÒÏÌÐÍÊÓÐÍÑÎËÒÏÌÑÎËÐÍÊÐÍÊÑÎËÓÐÍÎËÈÐÍÊÑÎËÐÍÊÏÌÉÎËÈÐÍÊÐÍÊÑÎËÎËÈÎËÈÏÌÉÌÉÆÏÌÉÎËÈÎÌÆÍËÅÎÌÆÌÊÄÎÌÆÌÊÄÏÍÇÊÈÂÎÌÆËÉÃÊÈÂÌÊÄËÉÃEEEEEEFFFGGGFFFFFFFFFGGGGGGEEEFFFGGGGGGHHHHHHHHHHHHEEE???888333111222555999>>>BBBEEEDDDDDDFFFFFFFFFFFFFFFEEEEEEEEEEEEFFFGGGFFFHHHHHHGGGHHHGGGHHHHHHHGIIHJGFHGFHFEGGFHFEGHGIFEGFEGFEGFEGFEGDCEDCEDCECBDCBDBAC@?A?>@=<>;:<:9;98:879768657546546546546333111...&&& !!!###$$$&&&&&&))))))))))))***++++++,+--,.-,..-/.-/.-/-.0-.0,-/,-/,-/+,../1457BDDLNNPQSPQSOPRPQSOPROPRPQSQRTUVXVWYXY[[\^\^^accdfffhhhjjjllkmmkmmkmmkmmkmmlnnoqqqssrtttvvvxxwyyxzzy{{}€}‚‡Š‡šš¨«¨•˜•cca11/!!"" #" #" #" #" "!#" #" #" #" $#!$#!%$"$#!%$"&%##" @@>˜˜–kmmƒƒ`de]ab_be_be`cfbehgjmgjmhknjmpmnpoprqrtstvxy{}~€„„„ŽŽŽ‘‘‘–––›š˜¡ ž§¤¢©¦¤¬©¦¯¬©±®«´±®·´±¹¶³½¸µ¿º·Á¼¹Á¼¹ÅÀ½ÅÀ½ÈÃÀÈÃÀÊÅÂÉÄÁÌÇÄËÆÃËÆÃÍÈÅÍÈÅÎÉÆÏÊÇÐËÈÏÊÇÑÌÉÑÌÉÑÌÉÑÌÉÑÌÉÒÍÊÓÎËÒÍÊÑÌÉÑÌÉÒÍÊÖÑÎÓÎËÓÐÍÒÏÌÎËÈÐÍÊÏÌÉÑÎËÐÍÊÎËÈÐÍÊÎËÈÍÊÇÐÍÊÑÎËÑÎËÏÌÉÐÍÊÑÎËÏÌÉÐÍÊÓÐÍÐÍÊÏÌÉÐÍÊÑÎËÍÊÇÏÌÉÎËÈÎËÈÎËÈÎËÈÐÍÊÏÌÉÌÉÆÐÍÊÎËÈÌÉÆÎËÈÌÉÆÑÏÉËÉÃÎÌÆËÉÃËÉÃËÉÃËÉÃÊÈÂËÉÃÌÊÄÈÆÀFFFEEEGGGFFFEEEFFFHHHFFFFFFGGGGGGGGGFFFFFFGGGGGGGGGHHHIIIIIIIIIGGGBBB???777444111222666;;;@@@DDDGGGFFFGGGFFFEEEFFFFFFGGGGGGGGGGGGIIIFFFHHHHHHIIIHHHJIKIHJHGIHGIHGIGFHGFHGFHFEGHGIFEGGFHFEGFEGFEGFEGGFHFEGEDFDCEEDFCBDBACA@B@?A>=?<;=98:98:768657546555666666444444111---''' ###%%%&&&(((((()))***)(**)++*,-,..-/-,.+,.,-/+,.,-/-.0,-/+,.,-/+--+--013=>@IJLPQSRSUPQSNOQMNPNOQOPRQRTSTVSUUVXXWYYZ\\_aaceefhhgiiikkjllikkikkkmmmoonppoqqqsstvvuwwuwwx{xx{xvyvx{x‚‰Œ‰žžœ©©§””’__]00.! #" #" "!#" #" #" $#!$#!$#!#" $#!%$"&%#"!nnl±±¯tvvsuu[_`[_`\_b_be_be`cfdgjehkfilhknklnmnpmnppqstuwyz|€€€………‘‘‘—–”œ›™£ ž¦£¡¨¥¢¬©¦¯¬©±®«µ²¯¶³°½¸µ¼·´À»¸Á¼¹Â½ºÆÁ¾ÅÀ½Ç¿ÆÁ¾ÉÄÁÊÅÂÉÄÁËÆÃÌÇÄÍÈÅÌÇÄÏÊÇÏÊÇÐËÈÎÉÆÑÌÉÐËÈÐËÈÑÌÉÐËÈÓÎËÑÌÉÐËÈÓÎËÒÍÊÒÍÊÓÎËÎËÈÐÍÊÏÌÉÏÌÉÏÌÉÐÍÊÑÎËÏÌÉÏÌÉÑÎËÎËÈÌÉÆÎËÈÊÇÄÎËÈÏÌÉÐÍÊÍÊÇÑÎËÎËÈÏÌÉÏÌÉÐÍÊÎËÈËÈÅÐÍÊÐÍÊÌÉÆÍÊÇÏÌÉÏÌÉËÈÅÍÊÇÍÊÇËÈÅÏÌÉÏÌÉÍÊÇÏÍÇÌÊÄËÉÃËÉÃÊÈÂÊÈÂÍËÅËÉÃÍËÅÉÇÁÇÅ¿FFDFFDGGEFFFGGGFFFGGGGGGJJJIIIGGGFFFHHHGGGGGGHHHGGGHHHHHHIIIIIIGGGIIIKKKKKKJJJHHHEEE<<<666333222333888===GGGGGGHHHFFFEEEGGGGGGFFFHHHGGGGGGHHHHHHIIIIIIIIIIIIHHHHHHIIIIHJGFHGFHGFHHGIGFHGFHGFHHGIHGIGFHHGIFEGFEGGFHDCEDCEEDFEDFCBDDCEA@B@?A?>@<;=:9;98:879666777444444333333333000***### !!!$$$$$$'''((()))(((***++++++,+-,+----,,,---------......///,..)++)++.008::CEELNNOQQOQQNPPMOOMOOMOOOQQQSSRTTTVVWYY]__bddegggiihjjfhhikklnnmoonppmoonppoqqprruuuvvvuusxxv{{yyyw||z‚‚€ŽŽŒ  ž¦©¦ZZX--+"!$#!#" "!#" #" #" #" $#!%$"&%##" HHFxxv’•’vyvVZ[W[\Z]`]`c]`c`cfadgdgjgjmfilijlijljkmnoqrsuvwy}}}ˆˆˆ”“‘—–”œš Ÿ¦£¡©¦¤«¨¥¯¬©²¯¬µ²¯¸³°»¶³¼·´¾¹¶¾¹¶Ã¾»Ã¾»Ã¾»ÆÁ¾Ç¿ÈÃÀÈÃÀÉÄÁËÆÃËÆÃËÆÃÎÉÆÌÇÄÑÌÉÍÈÅÑÌÉÍÈÅÏÊÇÏÊÇÐËÈÒÍÊÐËÈÒÍÊÔÏÌÑÌÉÒÍÊÏÊÇÑÌÉÒÍÊÐÍÊÐÍÊÏÌÉÏÌÉÏÌÉÏÌÉÏÌÉÒÏÌÍÊÇÎËÈËÈÅËÈÅÏÌÉÎËÈÎËÈÑÎËÎËÈÎËÈÐÍÊÏÌÉÎËÈÌÉÆÏÌÉÍÊÇÎËÈËÈÅÍÊÇÎËÈÎËÈÍÊÇÍÊÇÎËÈËÈÅÐÍÊÎËÈÍÊÇÌÊÄÌÊÄÊÈÂÌÊÄÌÊÄÏÍÇËÉÃËÉÃÉÇÁËÉÃËÉÃEECEECFFDEEEFFFHHHGGGHHHHHHHHHFFFFFFHHHHHHHHHHHHGGGGGGIIIJJJIIIHHHIIIIIIHHHHHHJJJJJJJJJLLLHHHFFFAAA:::555222222666;;;AAADDDFFFFFFHHHIIIFFFGGGFFFHHHIIIIIIJJJIIIIIIIIIHGIHGIHGIHGIIHJIHJHGIHGIIHJIHJGFHHGIGFHGFHGFHFEGFEGEDFFEGEDFEDFEDFBACBACCBD@?A?>@>=?;;;999888666555666444333555555333///***###"""$$$&&&&&&'''''')(*)(*******+++,,,,,,,,,,,,---,..-//,..,..*,,*,,*,,022=??IKKOQQOQQNPPLNNOQQNPPOQQPRRQSSSUUXZZ\^^`bbaccbddfhhjllmoomoomoolnnlnnpppqqqttrvvtwwuxxvyywzzx||z}ƒ†ƒ’¡¡Ÿ¦¦¤‹‹‰VVT,+) ! #" $#!$#!$#!%$"%$"%$"$#!66400./2/QTQSWXVZ[WZ]Y\_[^a^ad`cf_becfidgjghjijlijljkmnoqstvyyy}}}………‰‰‰“’™˜–œ›™¤¡Ÿ§¤¢©¦£­ª§¯¬©²¯¬¶±®¸³°¹´±¼·´¾¹¶¿º·Á¼¹Ã¾»ÅÀ½ÅÀ½ÆÁ¾ÆÁ¾ÉÄÁÈÃÀÉÄÁÊÅÂÍÈÅÐËÈÌÇÄÍÈÅÌÇÄÎÉÆÍÈÅÏÊÇÏÊÇÏÊÇÑÌÉÐËÈÏÊÇÒÍÊÐËÈÐËÈÐËÈÒÍÊÑÎËÎËÈÎËÈÏÌÉÎËÈÎËÈÐÍÊÏÌÉÎËÈÍÊÇÏÌÉËÈÅÍÊÇÊÇÄËÈÅÌÉÆÍÊÇÏÌÉÏÌÉÌÉÆËÈÅÑÎËÏÌÉÌÉÆËÈÅÌÉÆÎËÈËÈÅÍÊÇËÈÅÌÉÆÌÉÆÎËÈÎËÈÌÉÆÌÉÆÌÊÄÊÈÂÊÈÂÏÍÇÊÈÂÍËÅÉÇÁÉÇÁÊÈÂÉÇÁÊÈÂFFDFFDFFDFFDEECGGGIIIIIIGGGGGGGGGHHHIIIIIIHHHIIIIIIIIIJJJJJJIIIJJJJJJIIIIIIHHHIIIJJJJJJIIIKKKJJJLLLLLLLLLKKKGGG@@@;;;555444555:::===BBBGGGHHHHHHHHHHHHFFFGGGHHHHHHHHHHHHIIIIIIHHHIIIIIIHGIJIKIHJIHJHGIIHJHGIHGIIHJHGIGFHGFHGFHFEGEDFEDFEDFEDFFEGDCEEDFDCEBAC@?A?>@>=?:::888777777555666333222333444333///***######%%%''''''(((((())))))++++++,,,***+++,,,,,,,,,,,,---...---*,,)++.009;;FHHNPPOQQNPPLNNLNNMOOOQQPRRQSSSUUVXXXZZ\^^accfhhjllkmmlnnmoomoonppqqqrrrssqttrttrvvtxxvyyw||z||z~~|……ƒŽ¡¡Ÿ§§¥ˆˆ†RRP''% #" $#!%$"%$"&%#%$"888666444WWWUTVWVXWXZYZ\Y\_\_b^ad`cfbehcfighjhikijlklnmnpnoqvvvyyy„„„ŠŠŠŽŽŽ•”’˜—•Ÿœš¢Ÿ¥¢Ÿª§¤¬©¦­ª§°­ª³°­·²¯¹´±¼·´¾¹¶À»¸Â½ºÂ½ºÂ½ºÄ¿¼ÆÁ¾ÆÁ¾Ç¿ÉÄÁÊÅÂËÆÃÌÇÄÉÄÁÍÈÅÍÈÅÍÈÅÍÈÅÐËÈÍÈÅÎÉÆÐËÈÏÊÇÐËÈÑÌÉÐËÈÑÌÉÑÌÉÐËÈÑÌÉÏÊÇÎËÈÏÌÉÏÌÉÏÌÉÏÌÉÏÌÉÎËÈËÈÅÌÉÆÎËÈÍÊÇËÈÅËÈÅÊÇÄÌÉÆÌÉÆÎËÈÌÉÆÍÊÇÏÌÉÎËÈÊÇÄËÈÅÏÌÉÌÉÆÌÉÆÍÊÇÌÉÆÊÇÄÎËÈÎËÈÉÆÃÌÉÆÌÉÆËÉÃËÉÃËÉÃÏÍÇËÉÃÉÇÁÈÆÀËÉÃÌÊÄÊÈÂÌÊÄGGEGGEHHFGGEGGEGGGGGGJJJGGGHHHIIIHHHIIIJJJKKKJJJIIIHHHIIIIIIIIIKKKKKKIIIIIIIIIIIIKKKJJJJJJJJJJJJKKKIIIIIIJJJKKKMMMNNNOOOKKKEEE@@@777333222666<<>>DDDFFFGGGHHHGGGHHHHHHGGGIIIJJJHHHIIIJJJIIIHHHJJJIIIIIIJJJIIIHHHHGIHGIHGIGFHGFHGFHGFHGFHFEGFEGFEGFEGEDFDCECBDBACCBD@?A>=?;:<777777666444333222222222333222000---(((!!!###$$$'''''''''((()))***)))******+++++++++*,,*,,*,,*,,*,,)++)++022=??FHHMOONPPLNNLNNMOONPPNPPPRRRTTUWWY[[]___aafhhjjjjjjlljnnloomppnrrprrpssquusxxvyywyyw{{y}}{~~|€€~††„””’¢¢ ¥¥£††„NNL((&##!777666444WWWRSUSTVTUWUVXVY\X[^[^a]`c^bc`dedegdegefhghjijlklnnnnsssxxx}}}†††ŒŠ‘Ž”“‘™˜–Ÿœš¢Ÿ¦£ ª§¤ª§¤¬©¦°«¨¶±®¶±®·²¯»¶³¼·´¿º·À»¸Â½ºÁ¼¹Ä¿¼ÅÀ½ÆÁ¾Ç¿ÊÅÂÊÅÂÈÃÀÉÄÁÌÇÄÊÅÂËÆÃÎÉÆËÆÃÌÇÄÏÊÇÎÉÆÌÇÄÎÉÆÐËÈÏÊÇÎÉÆÎÉÆÎÉÆÏÊÇÏÊÇÎÉÆÎÉÆÎÉÆÑÌÉÎÉÆÍÈÅÑÌÉÎËÈÏÌÉÎÉÆÌÇÄÏÊÇÎÉÆÎÉÆÍÈÅÊÇÄÈÅÂÊÇÄÇÄÁÎËÈÊÇÄÌÉÆÊÇÄÌÉÆËÈÅËÈÅÍÊÇÎËÈÉÆÃÊÈÂÉÇÁÏÍÇÉÇÁÊÇÄÉÆÃÎÉÆÌÇÄÊÆÀËÇÁËÇÁËÇÁÊÆÀÊÆÀÊÆÀGGEFFDFFDFFDGGEIIIGGGGGGGGGIIIIIIJJJJJJIIIJJJIIIIIIIIIIIIKKKLLLKKKIIIKKKJJJJJJJJJKKKLLLKKKKKKJJJLLLLLLKKKKKKLLLKKKKKKKKKLLLJJJKKKLLLLLLLLLNNNOOONNNOOOHHHBBB;;;555222333555;;;@@@EEEIIIIIIGGGGGGHHHHHHIIIIIIHHHIIIJJJIIIHHHIIIHHHIHJJIKIHJHGIHGIGFHHGIGFHFEGGFHFEGFEGFEGEDFDCEDCEDCEEDFCBDDCEAAA???<<<;;;888666444444333222111111///000000,,,&&&!!!!!!$$$&&&''''''(((&&&'''((()))***(**(**(**)++)++*,,*,,*,,)++(**,..799CEELNNNPPOQQLNNLNNLNNOQQPRRQSSTVVXZZ^^^___ccajjhlljmmknnloomppnppnqqossqttrvvtyywyyw{{y~~|~~|}‡‡…””’¤¤¢¤¤¢‚‚€OOM555...222SSSPQSQRTQRTTUWUX[WZ]Y\_[^a\`a]ab`accdfcdfefhghjghjlllnnnssswww~~~‡†„Œ‹‰‘Ž•”’›˜–Ÿœš¡ž›¥¢Ÿ§¤¡ª§¤®©¦±¬©³®«¶±®¸³°¹´±¼·´¾¹¶¿º·¿º·Ã¾»Ã¾»ÅÀ½ÆÁ¾Ç¿ÆÁ¾ÉÄÁÇ¿ÊÅÂÈÃÀËÆÃËÆÃËÆÃÌÇÄÍÈÅËÆÃÌÇÄÍÈÅÎÉÆÌÇÄËÆÃÎÉÆÍÈÅÎÉÆÏÊÇÍÈÅÏÊÇÏÊÇÐËÈÌÇÄÍÈÅÎÉÆÌÉÆÐÍÊÍÈÅÌÇÄÏÊÇÏÊÇÌÇÄËÆÃËÈÅÊÇÄËÈÅÊÇÄËÈÅÍÊÇÊÇÄÉÆÃÉÆÃÉÆÃÊÇÄÌÉÆÊÇÄÊÇÄÉÇÁËÉÃÎÌÆÈÆÀÉÆÃÊÇÄÍÈÅÊÅÂÉÅ¿ÊÆÀËÇÁÉÅ¿ÊÆÀÊÆÀËÇÁGGEGGEHHFHHFIIGIIGIIGIIIIIIIIIJJJJJJJJJIIIIIIJJJHHHJJJKKKKKKLLLKKKJJJJJJJJJKKKMMMLLLLLLLLLLLLKKKKKKLLLKKKKKKLLLLLLLLLLLLKKKMMMNNNKKKLLLMMMNNNMMMLLLMMMNNNOOOPPPQQQMMMIIIBBB:::333000444999===BBBGGGGGGGGGEEEFFFGGGHHHIIIIIIIIIIIIJJJJJJIIIHHHJJJIIIIIIIIIIHJGFHGFHHGIGFHGFHFEGGFHGFHFEGEDFFEGEDFCBDDCEBACA@BA@B=<><;=879657444333333111111///111111///,,,&&&###%%%%%%&&&&&&''''''(((((()))*********(***,,*,,*,,)++)++)++)++022>@@JLLNPPNPPLNNLNNMOONPPNPPUUUVVVWWUZZXaa_ggeeeciigmmkoomoomqqoqqossqttruusxxxzzz{{{|||}}{}€€~……ƒ’•’£¦£¥¨¥…ˆ…VXXIKKFJKJNOOSTPTUSVYTWZW[\Y]^\]_\]_^_a_`babdcdfcdffgikkkmmmpppuuuxxx|||ƒƒƒ‡‡‡Ž‹“’—”’œ™—ž›™¢Ÿ¥¢Ÿ¨¥¢«¨¥®«¨±¬©³®«µ°­¸³°¹´±¼·´½¸µ¾¹¶À»¸Â½ºÃ¾»Ã¾»Ä¿¼ÆÁ¾Ç¿Ç¿ÈÃÀÉÄÁÊÅÂÉÄÁÉÄÁÊÅÂËÆÃËÆÃÊÅÂÏÊÇÍÈÅËÆÃÎÉÆÎÉÆÍÊÇÌÉÆËÈÅÊÇÄÍÊÇÊÇÄÌÇÄÎÉÆÏÊÇÍÈÅÏÊÇÎÉÆÍÈÅÌÇÄÍÈÅÍÈÅËÆÃÌÇÄÌÉÆÌÉÆËÈÅÍÊÇÈÅÂÈÅÂÊÇÄÊÇÄÊÇÄÈÅÂËÈÅËÈÅÈÅÂÊÇÄÉÇÁÌÊÄËÈÅÅ¿ÈÅÂÊÇÄËÆÃÊÅÂÊÆÀËÇÁÈľÌÈÂÈľÊÆÀÉÅ¿HHFGGEIIGHHFIIGJJHHHFIIIJJJIIIHHHJJJLLLJJJIIIJJJJJJJJJLLLLLLJJJKKKLLLKKKKKKKKKLLLKKKKKKLLLMMMKKKLLLMMMLLLKKKMMMMMMLLLKKKLLLMMMLLLMMMOOOMMMLLLMMMMMMNNNMMMNNNMMMMMMNNNMMMNNNPPPOOOMMMHHH???666333222555:::@@@DDDGGGFFFGGGFFFFFFGGGHHHIIIIIIHHHJJJHHHJJJJJJJIKHGIIHJJIKJIKIHJHGIHGIGFHGFHFEGGFHEDFEDFEDFEDFEDFDCEDCEDCECBD?>@;;;:::777555444333222000111000///000...***%%%###$$$&&&&&&&&&((('''(((((('))'))(**(**)++)++*,,+--*,,(**')),..799EGGLNNNPPNPPKMMNNNOOOPPNQQOSSQYYW[[Y]][bb`jjhkkinnlppnqqoqqorrpsssuuuvvvwwwwwuyyw}}{}}{||}€}ƒ†ƒ“–“¡££¤¦¦‰ŽcghMQRJNOORUSVYUYZW[\Z[]\]_^_a_`b`acabdbcecdfgggiiimmmpppvvvxxx~~~ƒƒƒ‡†„Ž‹“Ž—”’œ™—¡žœ£ ¤¡ž§¤¡ª§¤¯ª§°«¨³®«¶±®ºµ²»¶³»¶³½¸µ¿º·Á¼¹Á¼¹Ã¾»Á¼¹Ä¿¼ÆÁ¾ÆÁ¾ÈÃÀÇ¿ÈÃÀÇ¿ÈÃÀÊÅÂÌÇÄËÆÃÌÇÄÍÈÅÌÇÄÌÇÄÊÅÂÌÇÄÊÇÄÊÇÄËÈÅËÈÅËÈÅÌÉÆÌÇÄÐËÈÍÈÅÍÈÅÎÉÆÏÊÇÎÉÆÊÅÂËÆÃÐËÈÌÇÄÌÇÄÍÊÇÊÇÄÉÆÃÊÇÄÇÄÁÈÅÂÈÅÂÈÅÂÉÆÃÊÇÄËÈÅÉÆÃÈÅÂÉÆÃÉÇÁÊÈÂÇÄÁÉÆÃÉÆÃÈÅÂËÆÃÈÃÀÏËÅÉÅ¿ÉÅ¿ËÇÁÈľËÇÁÇýHHFHHFHHFIIGJJHIIGIIGJJJJJJKKKIIIIIIJJJKKKJJJIIIJJJKKKKKKKKKJJJKKKLLLKKKKKKKKKLLLLLLMMMMMMMMMMMMMMMMMMOOONNNLLLMMMLLLMMMMMMMMMLLLNNNLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNMMMMMMLLLMMMOOONNNPPPRRRQQQPPPLLLFFF===666333222555<<>><<<<<<888666444444222000000000000/////////***### ###%%%$$$%%%'''&&&'''((((((((()))******)++)++*,,*,,(**&(()++022?AAKMMNPPMOONNNMMMNNLQQOSSSTTTVVVZZZ^^^aaafffkkkooooooppprrrrrrrrrsssvvvwwuyyw||zyywzzz~~~ˆˆ†“–“£¦£¥¨¥‹Ž‹ceeOQQQSSVXXYZ\YZ\\]_[\^^_a_`babdbceeeegggkkkmmmrrruuuzzz~~~„ƒ‰ˆ†Ž‹’‘˜•’œ™–ž›˜£ ¥¢Ÿ¦£ ¨¥¢¬©¦²­ª²­ªµ°­·²¯ºµ²»¶³¿º·½¸µ¿º·Â½ºÀ»¸Â½ºÄ¿¼Ã¾»ÅÀ½ÆÁ¾ÊÅÂÉÄÁÉÄÁËÆÃÉÄÁÊÅÂËÆÃÊÅÂÈÅÂÈÅÂÎÉÆËÆÃÉÆÃËÈÅËÈÅÊÇÄÈÅÂÊÇÄÍÊÇËÈÅÎÉÆÎÉÆÍÈÅÎÉÆÌÈÂËÇÁÎÉÆÐËÈÆÁ¾ÍÈÅËÆÃÌÇÄËÆÃÌÇÄÈÅÂÉÆÃÉÆÃÊÇÄÇÄÁÉÆÃÉÆÃÈÅÂÈÅÂÉÆÃËÈÅÆÃÀÊÇÄÈÅÂÊÅÂËÆÃÉÅ¿ËÇÁËÇÁƼËÇÁÉÅ¿ÈľÊÆÀƼHHFIIGHHFIIGJJHHHFIIGIIIJJJKKKKKKIIIJJJJJJJJJKKKLLLKKKKKKLLLLLLLLLLLLKKKLLLLLLMMMLLLMMMNNNLLLOOOMMMNNNNNNNNNNNNMMMNNNOOOOOONNNMMMNNNNNNNNNNNNNNNNNNOOOOOONNNNNNOOONNNNNNNNNNNNNNNMMMNNNNNNMMMMMMPPPNNNPPPPPPPPPKKKCCC>>>777222444888>>>CCCFFFFFFFFFHHHFFFGGGHHHHHHIIIIIIHHHIIIHHHJJJJJJKKKGGGGGGHHHHHHGGGGFHGFHFEGGFHGFHHGIFEGDCEDDDDDDEEEAAAAAA>>>===999777444333222111000//////000///---)))###!!!###$$$$$$$$$&&&''''''(((((('))(**(**(**)++)++(**)++&((&((-//8::HHHNNNQQOOOMOOONNNOOOPPPSSSUUUXXX]]]___gggnnnmmmpppqqqsssqqqssqssquusvvtwww{{{}}{€€~~~‚…‚‰Œ‰”—”£¥¥¡££‡‰‰giiTUWSTVWXZZ[]]^`]^`_`b`acffffffhhhjjjmmmsssvvvzzz€}†…ƒŠ‰‡ŽŒ”‘Ž—”‘š—”ž›˜¡ž›¤¡ž§¤¡ª§¤®©¦±¬©´¯¬¶±®ºµ²¸³°¼·´¼·´¿º·Á¼¹Á¼¹Â½ºÄ¿¼Ã¾»ÅÀ½ÆÁ¾ÆÁ¾Ç¿Ç¿ÈÃÀÈÃÀÉÄÁÉÄÁÉÄÁÈÅÂÈÅÂËÆÃËÆÃÉÆÃÊÇÄÆÃÀÈÅÂÈÅÂËÈÅÊÇÄÉÆÃËÆÃÊÅÂËÆÃÌÇÄËÇÁËÇÁÊÅÂÈÃÀÌÇÄÎÉÆËÆÃËÆÃÌÇÄÇ¿ËÈÅÇÄÁÊÇÄÉÆÃÈÅÂÈÅÂÈÅÂÈÅÂÈÅÂÉÆÃÈÅÂÈÅÂÈÅÂÈÅÂÈÃÀÊÅÂÇýËÇÁÇýËÇÁÈľÆ¼ÉÅ¿ÇýÇýHHFHHFIIGIIGIIGIIGJJHHHHIIIKKKIIIJJJJJJLLLKKKLLLLLLMMMLLLLLLLLLNNNLLLMMMMMMLLLMMMNNNNNNMMMMMMLLLNNNNNNNNNNNNOOONNNOOOOOOOOOOOONNNPPPOOOPPPPPPOOOOOONNNMMMNNNNNNOOOOOOOOOOOOOOONNNOOOOOOMMMOOONNNMMMNNNMMMLLLLLLOOOPPPPPPQQQOOOHHHDDD999222000333;;;@@@AAAEEEFFFFFFEEEEEEFFFEEEEEEGGGHHHJJJGGGHHHHHHHHHIIIHHHGGGHHHHHHGFHGFHFFFFFFCEECEECEECEECCCBBBGGGCCCAAAAAA<<<999666444222111111000///...---...---)))!!!"""!!!$$$$$$&&&''''''&&&&&&((()))'))'))))))))***)))+++***))),,,666CCCNNNQQQPPPPPPNNNOOOQQQTTTVVVYYY]]]```dddkkkmmmooosssrrrrrrrrrtttuuuyyy{{{~~|~~|€€~‚‚€……ƒ‰‰‡––”§§¥¦¦¤‹‹‰giiVXXTVVZ\\^```bbddddddfffhhhkkknnnssswww{{y€€~†…ƒŒ‹‰Ž‹‘Ž—”‘›˜•Ÿœ™¢Ÿœ¥¢Ÿ§¤¡¬§¤®©¦±¬©´¯¬´¯¬·²¯ºµ²¼·´¼·´¿º·¿º·Á¼¹Â½ºÂ½ºÃÀ½Á¾»Â¿¼Å¿Å¿ÇÄÁÅ¿ÆÃÀÆÃÀÇÄÁÇÄÁÈÅÂÌÇÄÉÄÁÈÅÂÉÆÃÅ¿ÇÄÁÌÇÄÌÇÄÊÅÂËÆÃËÆÃÌÇÄÊÅÂËÆÃËÆÃÊÅÂÊÅÂËÆÃËÆÃÉÄÁÊÅÂËÆÃÌÇÄÈÃÀÎÉÆÅÀ½ÊÅÂÉÄÁÈÅÂÆÃÀÈÅÂÆÃÀÉÄÁÌÇÄÆÃÀÈÅÂÆÃÀÉÆÃÉÅ¿ÊÆÀÈľÈľÇýÉÅ¿ËÇÁƼƼƼÇýHHFIIGIIGIIGIIGJJHIIGIIIIIIKKKJJJLLLMMMMMMKKKKKKMMMLLLMMMMMMLLLNNNOOONNNLLLNNNNNNLLLNNNOOONNNMMMNNNNNNNNNNNNOOOPPPOOOOOOOOOPPPOOOPPPOOOOOOPPPPPPPPPOOONNNNNNNNNOOOOOOOOOPPPNNNNNNOOOPPPNNNOOONNNOOOPPPNNNMMMMMMOOOOOOOOONNNNNNOOOOOOQQQSSSQQQHHH???777111111555;;;???DDDEEECCCEEEDDDEEEEEEFFFHHHFFFGGGHHHHHHGGGHHHHHHIHJIHJHHHFFFDFFFHHEGGEGGEEEGGGFFFEEEDDDDDDCCCBBB@@@>>><<<999555333111000/////////......---+++((( !!!###"""$$$%%%%%%&&&&((&(((((((())))))******++++++***))))))111???JJJOOOQQQPPPOOOPPPRRRUUUWWWXXX]]]aaaeeehhhnnnrrrrrrrrrrrruuutttxxvzzx{{y~~|}ƒƒƒƒ‹‹‰™™—§©©¤¦¦‰‹‹giiXZZXZZbbbdddeeefffiiikkkooosssyyw}€}…„‚‰ˆ†ŒŠ”‘Ž—”‘š—”š—¢Ÿœ¥¢Ÿª¥¢­¨¥¯ª§²­ª³®«¶±®¸³°¹´±¼·´¿º·¼·´À»¸Á¼¹Â½ºÁ¾»Á¾»ÃÀ½ÄÁ¾ÃÀ½Å¿¿¼ÈÅÂÆÃÀÅ¿ÇÄÁÈÅÂÉÄÁÈÃÀÉÆÃÉÆÃÇÄÁÊÇÄÌÇÄÊÅÂÌÇÄËÆÃÉÄÁËÆÃÊÅÂÊÅÂÊÅÂËÆÃÈÃÀÊÅÂÊÅÂÊÅÂÊÅÂÊÅÂÊÅÂÉÄÁÊÅÂÈÃÀÈÃÀÊÅÂÆÃÀÅ¿ÇÄÁÆÃÀÈÃÀËÆÃÅ¿ÉÆÃÄÁ¾ÆÃÀƼÊÆÀÉÅ¿ÇýÈľÉÅ¿ËÇÁÄÀºÆ¼ÇýÅÁ»IIGJJHJJHHHHJJJLLJKKIJJJLLLKKKKKKLLLMMMMMMLLLKKKLLLMMMMMMMMMMMMNNNMMMNNNLLLNNNMMMMMMNNNNNNMMMNNNMMMOOOOOOOOONNNOOONNNNNNOOOPPPOOOOOOOOOPPPOOOPPPPPPPPPNNNPPPPPPOOOOOOOOOPPPOOOQQQPPPPPPPPPPPPQQQOOOPPPPPPOOOOOOPPPPPPOOOPPPPPPQQQOOONNNOOOOOOPPPRRRRRRSSSNNNGGG===444111222555===AAADDDCCCEEECCCCCCCCCDDDEEEEEEFFFFFFEEEGGGFHHFHHGIIGIIFHHFHHEGGFHHEGGEGGDFFEGGCEEACCBBBAAABBBAAA??????:::888555333111000///............---,,,&&&!!!"""###%%%&&&'''&&&'''''''''((((((((()))***************))),,,999FFFPPPPPPOOOQQQRRRRRRSSSWWWZZZ]]]```fffmmmooonnnqqqrrruusuusuuswwuyyw||z~~|~~|€€~„„‚‹‹‰››™©©§¦¦¤ŠŠˆkki]][___bbbfffiiikkkooottr{{y}|z€~„ƒŠ‰‡Ž‹•’š—”ž›˜¡ž›¥¢Ÿ¨¥¢®©¦¯ª§³®«´¯¬¶±®¸³°¼·´»¶³¼·´¿º·Á¼¹Â½ºÁ¾»Á¾»Á¾»ÃÀ½ÄÁ¾ÄÁ¾ÇÄÁÆÃÀÆÃÀÆÃÀÅ¿ÆÃÀÅ¿ÇÄÁÇÄÁÇÄÁÈÃÀÈÃÀÉÄÁÈÃÀÊÅÂÈÃÀÈľÉÅ¿ÈľÊÆÀÈľÇýÉÅ¿ËÇÁÈľÊÆÀÉÅ¿ËÇÁÈľÉÅ¿ÇýÉÅ¿ÇýÉÅ¿ÉÅ¿ÉÅ¿Ç¿ÈÃÀÉÄÁÈÃÀÈľÇýÇýÇýÊÆÀÊÆÀÇýÇýÇýÈľÆ¼ÄÀºÈľÆ¼ÇýHHFJJHJJHJJJKKKIIGIIGJJJJJJKKKKKKMMMKKKKKKLLLMMMKKKLLLMMMOOOMMMLLLKKKNNNNNNNNNNNNOOOOOOOOOOOONNNOOOOOOOOOOOONNNOOOOOOOOOOOOPPPPPPQQQPPPPPPOOONNNOOOPPPPPPPPPOOOOOOPPPOOOOOOOOOPPPQQQPPPPPPQQQNNNPPPPPPPPPQQQPPPPPPPPPQQQPPPQQQPPPPPPPPPOOOOOOOOOPPPOOOOOOQQQRRRRRRSSSQQQMMMDDD:::333111333777>>>BBBEEECCCCCCAAADDDCCCCCCCCCBDDBDDBDDEGGEGGFHHFHHHJJFHHFHHEGGFHHEGGBDDEEEEEECCCCCCDDDBBBBBBAAABBB===:::888555222000...///...---,,,---+++***&&&!!!$$$&&&%%%%%%&&&&&&'''((((((((()))******+++,,,***)))+++111@@@MMMRRRTTTQQQQQQRRRTTTWWWYYY^^^ccchhhkkknnnqqossqrrpuusttrttrwwuzzx{{y~~|€€~ƒƒ††„ŒŒŠœœš¨¨¦¥¥£‹‹‹lll___bbbhhhnnnqqoxxvzyw~}{€~…„‚ˆ‡…Œ‹‰“—”‘›˜•Ÿœ™¤¡ž¦£ ª¥¢¯ª§°«¨²­ªµ°­·²¯·²¯¸³°ºµ²½¸µ¾¹¶¿º·¼¹¶¿¼¹À½ºÀ½ºÀ½ºÂ¿¼Å¿¿¼ÃÀ½ÃÀ½Å¿Å¿ÇÄÁÇÄÁÅ¿ÄÁ¾Ç¿Ç¿ÈÃÀÉÄÁÈÃÀÈÃÀÉÅ¿ÈľÊÆÀÈľÈľÈľÊÆÀÉſƼËÇÁÈľÆ¼ÅÁ»ÈľÇýËÇÁÇýƼÇýÈľÇ¿ÊÅÂÈÃÀǿƼƼÇýÊÆÀÊÆÀƼƼÉſƼÇýÉÅ¿ÅÁ»ÉÅ¿ÇýƼIIGKKIJJHKKIKKIJJHKKIKKKKKKLLLMMMJLLKMMJLLJLLLLLKKKLLLMMMMMMNNNMMMMMMNNNNNNNNNOOOOOOMMMOOOPPPOOOOOOOOOOOOOOOOOOOOOPPPPPPOOOOOOQQQQQQRRRQQQPPPPPPPPPQQQPPPPPPOOOQQQPPPOOOPPPPPPPPPQQQPPPPPPQQQQQQPPPPPPQQQQQQPPPQQQQQQOOOPPPOOORRRPPPPPPPPPOOORRRQQQPPPQQQQQQRRRQQQQQQPPPPPPPPPRRRSSSPPPJJJAAA999111111444888===BBBCCCACC@BB@BB>@@?AA?AAACCACCACCBDDDFFDFFFHHHJJFHHEGGDFFEGGEGGCEEDFFCEEEGGCEEBDDACC@BB?AA?AA=??;==577444222000......---...,,,---+++(((### !!!$$$&&&&&&&&&&&&&&&''''''&((&(()))******,,,,,,))))))---888GGGQQQSSSSSSSSSSSSVVVWWW\\\___aaahhfmmkoomppnssqssquusvvtwwuyywzzx{{y~~|„„‚ˆˆ†‹œœš¨¨¦££¡ŠŠˆnnlddbkkissqyyw}ƒ‚€ˆ‡…Œ‹‰••‘šš– š¥¢Ÿ¨¥¢«¨¥®«¨¯¬©³°­¶³°¹¶³º·´º·´¼¹¶¾»¸À½ºÀ½ºÀ½ºÁ¾»Á¾»À½ºÂ¿¼Ä¼ÃÁ»ÃÁ»ÂÀºÆľÈÆÀÅýÃÁ»Ä¼Ä¼Ä¼ÅýÈľÇýÈľÊÆÀÉÅ¿ÊÆÀÇýÈľÇýÇýÊÆÀÈľÉÅ¿ÈľÈľÉÅ¿ÈľÆ¼Æ¼ÈľÇýÈľÇýÉÅ¿ÈľÅÁ»ÈľÇýÇýÈľÈľÇýÇýÉſƼÇýÇýƼÇýƼÇýÅÁ»Æ¼ÇýÅÁ»JJHJJHKKIKKIJJHKKIKKIKKKKKKLLLKKKIKKIKKKMMKMMMMMMMMLLLMMMNNNMMMOOONNNPPPOOONNNPPPQQQNNNOOOPPPPPPOOOOOOPPPOOOOOOOOOPPPPPPRRRQQQRRRQQQQQQRRRPPPPPPQQQPPPPPPQQQPPPQQQPPPPPPOOOQQQQQQQQQPPPQQQRRRRRRQQQSSSRRRRRRQQQQQQSSSRRRQQQRRRQQQPPPQQQRRRQQQQQQQQQQQQQQQRRRRRRQQQRRRRRRPPPQQQPPPPPPQQQQQQOOOQQQRRROOOIII===777111///4668::?AA@BBACC@BB?AA?AA>@@>@@?AA?AA@BBBDDCEEEGGEGGEGGFHHFHHEGGFHHFHHFHHFHHEGGCEEACC@BB?AA@BB>@@@@@>>>:::888666111///...---,,,+++,,,++++++(((###!!!###$$$%%%'''%''$&&'''((())))))))))))***++++++***,,,444CCCOOOTTTTTTTTTUUUWWWWWW[[Yaa_eechhfkkimmkrrpssqttruusvvtwwuyyw{{y}}{}‚‚€……ƒ‰‰‡œœš¨¨¦››™ffd553##!##!$#!&%#*)'*)'00,440963=:7A>;C@=GDALIFPMJVSP^[Xeb_hebmjgtqnzwt|yƒ€}‡„Œ‰†•’˜•’š˜’žœ–£¡›¨¦ ©§¡™—‘ÃÁ»ÃÁ»ÃÁ»ÅýļļÇýƼƼÇýÈľÊÆÀƼÅÁ»Æ¼Æ¼ÊÆÀƼÇýÄÀºÆ¼Æ¼Çýÿ¹ÅÁ»ÊÆÀƼÇýÊÆÀÇýƼƼƼƼÉſƼƼƼƼÅÁ»Æ¼Æ¼ÅÁ»ÇýÈľÅÁ»Æ¼ÿ¹ÅÁ»ÄÀºÃ¿¹IIGKKIKKIJJJIIIJJJMMMKKKKKKLLLLLLJLLJLLMMMNNNLLLNNNLLLLLLOOONNNMMMNNNPPPOOOOOOOOOOQQMOOPPPPPPPPPOOOPPPQQQPPPOOOPPPQQQQQQQQQQQQQQQQQQRRRQQQQQQQQQQQQQQQQQQRRRRRRRRRRRRQQQRRRRRRRRRRRRRRRSSSSSSRRRRRRRRRRRRRRRRRRQQQRRRSSSQQQQQQPPPQQQRRRSSSRRRSSSPPPSSSRRRRRRRRRQQQQQQQQQQQQQQQRRRQQQQQQQQQQQQPPPOOOQQQQQQSSSSSSSSSPPPHHH<<<244.00/11466;;;AAABDD@BB@BB>@@@@@@@@@@@AAA@@@AAA?AACEEEGGFHHFHHHJJGIIGIIFHHDFFCEECEEBDDACC@BBACCBBB@@@???>>><<<888333111///...,,,,,,---,,,******&(( """""###$$$"$$#%%'''''')))(((((()))+++,,,,,,,,,******222;;;JJJTTTXXXVVVVVVYYY\\Z\\Z__]ddbhhfmmkoomqqorrpuusvvtwwuxxvzzx||z}}{}„„‚††„‰‰‡Ž›¨¨¦––”aa_..,! ! »¹³ÅýÅÁ»Æ¼Æ¼ÇýÈľÆ¼ÅÁ»ÈľÇýÈľÆ¼¾¸Ã¿¹Æ¼ÇýÄÀºÂ¾¸ÊÆÀÉÅ¿ÈľÄÀºÆ¼Æ¼ÇýÇýÄÀºÇýÅÁ»Æ¼ÿ¹ÄÀºËÇÁÅÁ»ÄÀºÇýÅÁ»Æ¼Æ¼ÄÀºÃ¿¹ÅÁ»ÄÀºÅÁ»ÅÁ»ÅÁ»Á½·Çýÿ¹Ã¿¹IIGKKIKKIJJJJJJKKKLLLKKKLLLLLLMMMKMMJLLMMMLLLMMMMMMMMMMMMNNNNNNNNNOOOOOONNNOOOOOOMOOMOOQQQNNNQQQQQQPPPRRROOOPPPQQQPPPQQQQQQQQQRRRSSSRRRQQQRRRRRRSSSRRRRRRRRRSSSRRRRRRSSSSSSTTTSSSRRRSSSTTTTTTSSSSSSTTTSSSRRRSSSSSSRRRTTTRRRQQQQQQQQQSSSRRRQQQRRRRRRRRRTTTTTTRRRSSSRRRQQQQQQQQQQQQRRRRRRSSSRRRRRRQQQRRRQQQQQQPPPPPPPPPQQQRRRRTTQSSKMM@BB999333-//.00688<>>@@@BBBBBB@@@???>>><>><>>=???AA@BBACCBDDDFFEGGFHHCEEFHHDFFDFFFHHDFFDDDCCCBBBBBB@@@@@@BBB@@@<<<888444000......,,,+++(**'))***)))&&&""" ""!#####$$$&&&'''&&&'''''')))***++++++++++++******---777FFFSSSXXXZZXXXVXXV\\Z__]bb`ggejjhjjhnnlssquusvvtxxvwwuxxvyyw{{y~~|‚‚€……ƒ‡‡…‰‰‡‘‘¡¡Ÿ©©§““‘^][-,*    !µ³­ÃÁ»ÇýÅÁ»ÅÁ»ÇýƼƼƼÇýƼƼÇý¾¸ÅÁ»Æ¼ÉÅ¿ÄÀºÅÁ»ÊÆÀÅÁ»Ã¿¹ÄÀºÆ¼Æ¼ÄÀºÆ¼ÄÀºÃ¿¹ÅÁ»Æ¼ÿ¹Æ¼ÅÁ»Ã¿¹ÅÁ»ÄÀºÇýƼÿ¹Ã¿¹Â¾¸Æ¼ÅÁ»ÅÁ»ÄÀºÃ¿¹ÄÀºÂ¾¸ÄÀºÀ¼¶JJHLLJKKIJJJMMMLLLKKKLLLLLLLLLMMMLLLKKKMMMNNNMMMNNNOOOMMMNNNMMMNNNPPPOOONNNPPPNNNOOOQQQPPPOOOPPPPPPPPPQQQPPPPPPQQQRRRQQQPPPQQQSSSSSSRRRQQQRRRRRRQQQRRRSSSRRRSSSSSSSSSTTTSSSTTTSSSSSSTTTTTTSSSTTTSSSUUUTTTTTTTTTSSSTTTSSSRRRRRRQQQQQQRRRSSSQQQRRRSSSRRRTTTRRRSSSSSSRRRRRRRRRSSSRRRRRRRRRSSSRRRRRRRRRRRRQQQQQQQQQQQQQQQOOOQQQQQQPPPPPPRRRRRRTTTRRRKKKCCC888000000444999>>>@@@?AA>@@=??>@@=??>@@=??>@@>@@?AA?AACEECEEEGGFHHFHHDFFEGGEEEDDDDDDCCCDDDCCCBBBAAAAAA???:::999333111...,,,)++(**'))'))(**'))%%%!!! """$$$$$$&&&&&&((((((((()))******+++,,,,,,******333@@@QQQZZX]][\\Z\\Z]][``^aa_ggeiiglljppnqqottrttruusvvtxxvyyw{{y~~|€€~ƒƒ……ƒ‡‡…‹‹‰““‘  ž©©§WWU('% !²°ªÄ¼ÅÁ»ÅÁ»Ã¿¹ÅÁ»Ã¿¹ÅÁ»Æ¼Æ¼ÇýÅÁ»ÈľÁ½·Ã¿¹ÅÁ»ÈľÅÁ»Çýÿ¹ÄÀºÃ¿¹Æ¼Æ¼ÿ¹Ã¿¹Æ¼ÅÁ»ÅÁ»ÄÀºÃ¿¹Â¾¸ÅÁ»ÄÀºÄÀºÅÁ»ÄÀºÄÀºÃ¿¹Â¾¸ÅÁ»Â¾¸ÇýƼƼ¾¸Â¾¸Ã¿¹ÄÀºÅÁ»Ä¼IIGJJHJJHKKKKKKLLLLLLKKKLLLLLLLLLMMMNNNKKKMMMLLLNNNOOOLLLMMMOOONNNNNNNNNPPPPPPPPPPPPPPPPPPOOOPPPOOOPPPPPPQQQRRRQQQRRRRRRQQQPPPQQQRRRRRRRRRRRRSSSQQQRRRTTTRRRRRRRRRSSSSSSSSSSSSTTTTTTTTTTTTSSSTTTUUUTTTTTTTTTUUUSSSTTTUUUTTTSSSTTTTTTSSSRRRQQQSSSUUURRRSSSTTTUUUSSSSSSTTTSSSSSSRRRRRRSSSSSSTTTSSSRRRRRRSSSSSSRRRRRRQQQRRRQQQRRRQQQRRRQQQQQQPPPQQQOOOQQQSSSSSSPPPIII@@@666///-//2448::<>>=??>@@>@@=??;===??=??<>>=??>@@?AAACCACCBDDDDDFFFFFFEEEFFFEEEDDDCCCCCCAAACCCBBBBBBBBB===999355.00,..)++(**(**)))***((('''%%% ###$$$$$$'''''''''(((******+++,,,...---******..,;;9LLJZZX]][]][\\Z]][``^ddbffdiiglljoomqqorrpuusuusvvtzzxzzx||z}ƒƒ……ƒˆˆ†ŠŠˆ““‘  ž¨§¥ŽŒVUS$#!GFD,+)320%$"IHF('%=<:+*(653 ¶´®Ä¼ÿ¹ÄÀºÄÀºÃ¿¹ÇýÄÀºÅÁ»ÄÀºÆ¼ÄÀºÄÀºÁ½·ÄÀºÅÁ»ÅÁ»Ã¿¹ÅÁ»Â¾¸ÄÀºÄÀºÅÁ»ÄÀºÁ½·ÅÁ»ÄÀºÆ¼ÄÀºÂ¾¸Ã¿¹Ã¿¹Æ¼¾¸Ã¿¹Æ¼Æ¼ÅÁ»ÄÀºÃ¿¹Â¾¸ÅÁ»ÄÀºÃ¿¹Á½·Á½·ÄÀºÇýƼ¥¡›}{uKKIKKIJJHJJJMMMKKKKKKLLLLLLMMMMMMLLLMMMLLLMMMLLLNNNMMMMMMNNNOOOPPPNNNMOONPPMOONPPMOONPPPPPPPPPPPPPPPPPQQQRRRRRRQQQQQQSSSSSSRRRSSSRRRSSSRRRRRRRRRRRRSSSSSSSSSSSSTTTSSSTTTSSSSSSSSSTTTUUUUUUTTTUUUTTTTTTUUUTTTTTTUUUUUUUUUTTTUUUVVVTTTTTTSSSSSSTTTSSSSSSSSSTTTTTTSSSTTTSSSSSSRRRSSSTTTSSSSSSUUUSSSSSSTTTUUURRRSSSSSSSSSTTTRRRRRRTTTTTTRRRRRRQQQQQQQQQPPPQQQQQQQQQRRRSSSTTTSSSOOODDD;;;333...000466:<<=??>@@>@@=??=??<>>=??;=====>>>???@@@BBB@@@CCCDDDFFFEEEEEEDDDEEEEEECCCDDDBDDBDDACC@BB<>>8::577022,..*,,***)))))))))(((&&&$$$!!!###&&&%%%%%%&&&((())))))+++++++++,,,+++,,,***,,,777IIIXXV``^aa___]aa_aa_ddbffdjjhmmkppnrrpttrwwuwwuxxvyywzzx}}{€€~‚‚€„„‚……ƒ‡‡…ŠŠˆ••“¤¤¢¥¥£–•“NMK'&$;:8"!66200,@=:¸¶°ÃÁ»ÄÀºÄÀºÃ¿¹Ã¿¹ÄÀºÆ¼ÿ¹Ã¿¹ÄÀºÄÀºÂ¾¸Á½·Ã¿¹ÄÀºÅÁ»Ã¿¹Ã¿¹Â¾¸ÄÀºÃ¿¹ÄÀºÀ¼¶¿»µÄÀºÂ¾¸ÄÀºÄÀºÂ¾¸Ã¿¹Â¾¸ÄÀºÂ¾¸Ã¿¹ÄÀºÁ½·Ã¿¹ÄÀºÃ¿¹Á½·Ã¿¹Â¾¸Ã¿¹ÅÁ»Ã¿¹ÁÀ¾–•“_cjAEL8=GJJHIIGKKIKKKJJJLLLKKKLLLMMMLLLLLLMMMLLLNNNNNNLLLMMMMMMNNNNNNPPPNNNOOOLNNMOONPPNPPMOOMOORRRPPPPPPQQQQQQQQQRRRRRRRRRRRRQQQRRRSSSRRRRRRRRRRRRSSSRRRRRRRRRSSSSSSSSSSSSTTTTTTUUUTTTSSSSSSTTTTTTUUUTTTTTTSSSUUUTTTTTTTTTUUUUUUUUUTTTUUUUUUUUUTTTVVVUUUTTTTTTTTTTTTTTTTTTUUUTTTSSSTTTUUUTTTSSSUUUTTTUUUSSSSSSTTTTTTSSSTTTTTTTTTTTTTTTSSSRRRSSSTTTSSSSSSRRRRRRRRRSSSQQQRRRRRRPPPPPPQQQQQQSSSTTTSSSLLLBDD688/11,..022577;===??>@@=??>>>>>>????????????>>>??????@@@CCCFFFFFFEEEDDDEEEBDDCEE@BB@BBACCBDDBDDCEEACC<>>888333///---+++)))((()))(((%%%###!!!###$$$&&&&&&&&&'''((()))***+++---------,,,+++,,*220@@>SSQ__]bb`aa___]aa_ccaggehhflljoomqqottrvvtxxvzzx{{y||z~~|€€~„„‚……ƒ„„‚††„ŠŠˆ–•“¥¤¢£¢ ~}{BA?¹·±ÂÀºÄÀºÃ¿¹Ã¿¹Ã¿¹Ã¿¹ÅÁ»Â¾¸Á½·Â¾¸Ã¿¹Á½·Â¾¸Â¾¸À¼¶ÅÁ»Â¾¸ÄÀºÃ¿¹À¼¶Â¾¸ÄÀºÁ½·Â¾¸ÄÀºÁ½·Â¾¸Ã¿¹À¼¶Â¾¸Â¾¸Ã¿¹Â¾¸ÄÀºÁ½·Á½·Â¾¸Ã¿¹Á½·Á½·Á½·Á½·Â¾¸ÅÁ»½¹³€~`_]cgn]ahMR\HHFKKKKKKKKKLLLKKKKKKLLLLLLLLLMMMMMMMMMLLLMMMMMMMMMNNNOOONNNNNNMOOMOOMOOLNNNPPNPPMOONPPRRRSSSPPPPPPQQQQQQQQQRRRQQQPPPRRRRRRRRRRRRQQQRRRSSSRRRRRRQQQRRRSSSSSSRRRTTTRRRSSSTTTTTTTTTTTTUUUTTTUUUUUUUUUTTTUUUTTTUUUUUUTTTUUUTTTUUUVVVUUUUUUSSSTTTUUUVVVUUUTTTTTTTTTUUUVVVVVVSSSTTTTTTTTTTTTTTTUUUSSSUUUUUUUUUTTTTTTUUUUUUUUUTTTTTTSSSRRRTTTTTTTTTRRRSSSSSSTTTRRRRRRQQQRRRRRRQQQQQQQQQRRRPPPPPPRRRQQQTTTTVVPRRJLLACC355.00///333888<<>>??????????????????AAADDDCEEDFFEGGEGGEGGDFFDFFCEECEEGIIDFFDFFEGGFHHFFF???;;;555000,,,***)))***((()))'''"""!!!$$$%%%''''''(((((()))***+++,,,,,,---...---,,,---999MMM\\\ccccccbbbcccddbggejjhmmkppnssquusvvtxxv{{y{{y||z~~|€€~‚‚€……ƒ……ƒ‰‰‡‹——•££¡™™—oom775¾¼¶ÂÀºÃ¿¹Â¾¸Â¾¸Ã¿¹Â¾¸Â¾¸À¼¶Á½·À¼¶À¼¶¿»µ¾º´¾º´Â¾¸Â¾¸Á½·Á½·¿»µ¿»µÃ¿¹Á½·¿»µÂ¾¸Á½·Â¾¸Á½·Â¾¸Á½·Á½·Ã¿¹Á½·Ã¿¹Ã¿¹Á½·À¼¶Á½·À¼¶Ã¿¹À¼¶À¼¶Á½·Â¾¸ºº¶eea>KUBOY>>======>>>=??>@@ACCDFFFHHFHHDFFCEEFHHGIIFHHEGGGIIEGGGGGGGGGGGIIIFFFCCC:::555111---***)))((()))(((&&& ###%%%&&&''''''))))))***+++------...///...---...444DDDVVVaaaccaccaddbddbffdhhfkkinnlppnuuswwuyywzzx||z||z€€~€€~ƒƒ„„‚ˆˆ†ŠŠˆŽŽŒ””’——•‰ˆ†_^\10.Á¿¹Á¿¹Á½·Á½·À¼¶À¼¶¿»µ¿»µ¿»µ¼¸²½¹³»·±º¶°º¶°»·±»·±¼¸²½¹³¾º´¾º´½¹³¿»µ¿»µ½¹³¿»µ¿»µÂ¾¸À¼¶À¼¶À¼¶Á½·Á½·À¼¶Á½·Á½·À¼¶À¼¶Â¾¸À¼¶Â¾¸¿»µÂ¾¸Ã¿¹ÄÀº}AA=FS]Ubl0I_5K!7NJJHJJHKKIJJJKKKJJJKKKKKKLLLLLLKKKMMMMMMMMMMMMLLLNNNNNNNNNOOOPPPMOONPPNPPNPPNPPMOONPPMOOPPPQQQQQQQQQRRRRRRSSSQQQQQQRRRRRRPPPPPPRRRRRRRRRSSSTTTSSSTTTSSSRRRTTTUUUTTTTTTUUUTTTTTTSSSUUUUUUUUUUUUTTTTTTTTTTTTTTTUUUUUUUUUUUUUUUUUUTTTUUUUUUTTTTTTUUUTTTUUUTTTUUUUUUVVVVVVUUUWWWWWWWWWVVVVVVTTTVVVUUUTTTUUUUUUUUUVVVVVVUUUUUUVVVUUUUUUUUUUUUTTTTTTUUUUUUUUUTTTSSSSSSTTTTTTTTTUUUSSSSSSSSSRRRSSSRRRQQQSSSRRRSSSRTTQSSRRRRRRRRRSSSUUUUUUUUUSSSFFF<<<333000222999???@@@>>>>>><>><>><>>=???AACEEEGGFHHHJJHJJFHHFHHHJJHJJIIIIIIHHHGGGHHHHHHGGGEEEDDDCCC???888222...+++***+++((('''%%%$$$&&&'''***((()))***,,,......///000000000...111>>>QQQ__]eecddddddffdffdiiglljppnttrvvtxxvyywzzx}}{}}„„‚‡‡…ˆˆ†ŠŠˆ‹ŽŽ||zQPN)(&//+ÃÁ»¾¼¶À¼¶À¼¶¾º´¾º´»·±¼¸²º¶°·³­¸´®¶²¬¶²¬¶²¬µ±«¸´®¼¸²¶²¬»·±¼¸²¼¸²»·±»·±¾º´¾º´»·±½¹³¾º´¼¸²¾º´Á½·¿»µ½¹³Á½·À¼¶Á½·¾º´Á½·Â¾¸¿»µ¾º´Â¾¸Ä¼›•@BHKMSTYh>CR+3?*2>&,7JJHKKILLJKKKLLLKKKLLLLLLKKKMMMLLLMMMLLLLLLNNNNNNOOONNNNNNNNNNNNMOOOQQNPPMOOMOOMOONPPNPPRRRRRRQQQQQQRRRQQQRRRQQQRRRRRRPPPQQQSSSTTTSSSSSSSSSTTTTTTTTTSSSSSSTTTTTTSSSTTTTTTUUUTTTUUUSSSTTTTTTUUUTTTTTTUUUTTTUUUUUUTTTTTTTTTVVVUUUTTTVVVTTTTTTTTTVVVTTTSSSTTTVVVVVVWWWWWWVVVVVVVVVWWWWWWVVVUUUUUUUUUWWWUUUUUUUUUUUUVVVVVVUUUVVVVVVVVVUUUVVVUUUTTTUUUUUUTTTTTTTTTTTTTTTUUUUUUUUUTTTTTTUUUUUUTTTTTTTTTSSSQQQRRRRTTPRRSSSSSSSSSSSSSSSRRRSSSRRRSSSUUUVVVTTTMMMBBB999333111555799:<<=??@BB>@@?AADFFFHHFHHFHHGIIKMMKMMKMMKKKLLLKKKKKKLLLJJJHHHHHHFFFGGGGGGHHHIIIEEEBBB:::444///,,,******+++)))&&&!!!"""&&&'''))))))***---------///00022222211100011/997JJJ[[[eecffdddbddbeechhfkkioomrrpttrxxv{{y}}{}}{~~|€€~‚‚€„„‚‡‡…‡‡…ŠŠˆŠŠˆˆ‡…„ƒgfd431##551PPL©©¥ÂÀº½»µ¿»µ¼¸²º¶°¹µ¯·³­¶²¬µ±«²®¨³¯©²®¨³¯©±­§²®¨µ±«´°ª²®¨¶²¬´°ªµ±«´°ª¹µ¯·³­¸´®¸´®»·±º¶°¹µ¯¼¸²»·±¸´®»·±¿»µ½¹³½¹³½¹³½¹³¾º´¾º´¿»µÅÁ»¨¦ b`Z<>DLNT5:I.3B,4@"*6"(3JJHJJHKKILLLKKKLLLMMMLLLLLLMMMLLLMMMNNNOOOMMMOOONNNMMMMMMOOOOOOMOOMOONPPLNNMOONPPOQQOQQPPPPPPRRRRRRRRRQQQRRRRRRRRRRRRTTTQQQSSSSSSTTTSSSTTTSSSTTTSSSSSSTTTTTTSSSTTTTTTTTTUUUUUUTTTUUUTTTUUUUUUTTTUUUUUUWWWUUUVVVUUUWWWVVVVVVWWWVVVVVVUUUUUUUUUUUUUUUSSSTTTWWWVVVXXXWWWWWWVVVVVVVVVWWWWWWWWWWWWXXXWWWVVVVVVWWWWWWWWWWWWVVVWWWWWWVVVWWWUUUWWWVVVUUUVVVTTTUUUSSSUUUTTTUUUUUUVVVUUUUUUVVVUUUUUUTTTVVVVVVSSSTTTUUUTTTUUUTTTSSSTTTUUUTTTTTTUUUSSSSSSRRRRRRRRRTTTVVVVVVRRRKKK>>>333000111777>>>?AACEEHJJHJJGIIJLLIKKLNNMMMKKKKKKLLLMMMMMMKKKKKKLLLLLLJJJJJJKKKJJJJJJKKKLLLJJJCCC;;;666000---)))++++++'''&&&!!! &&&(((***+++++++++---///000222111222222222222444AAAVVVbbbfffeeeeeeggghhfjjhppnrrpwwuwwuzzx~~|}}‚‚€ƒƒ……ƒ‡‡…„„‚€€~{{yXWU.-+! ‚ÂÀºÂÀº¿»´½¹²¼¸±½¹²·³­µ±«±­§±­§±­§¯«¥­©£¬¨¢¯¨£®§¢¬¥ ±ª¥³¬§²«¦´­¨´­¨³¬§µ®©¸´®µ±«¸´®´°ª¶²¬³¯©¶²¬¸´®·³­¹µ¯¹µ¯½¹³¹µ¯¼¸²º¶°¾º´¿»µ»·±Á¿¹Á¿¹kkoHHL?-*1*&-&")+%,KKIIIGIIGJJJKKKKKKLLLMMMLLLKKKKKKJJJMMMNNNLLLNNNNNNMMMMMMMMMPPPNPPLNNLNNMOONPPNPPNPPMOOPPPQQQPPPQQQRRRRRRSSSRRRRRRRRRSSSSSSRRRSSSTTTRRRRRRRRRTTTSSSSSSTTTTTTTTTSSSTTTTTTUUUUUUTTTUUUUUUWWWVVVUUUUUUUUUWWWVVVVVVVVVUUUWWWVVVVVVWWWWWWWWWVVVUUUUUUUUUSSSTTTTTTTTTUUUVVVTTTWWWVVVWWWWWWWWWVVVVVVWWWWWWVVVXXXVVVWWWWWWWWWVVVWWWVVVWWWWWWVVVWWWUUUTTTTTTVVVUUUUUUUUUVVVUUUVVVWWWUUUUUUVVVVVVUUUTTTUUUVVVUUUVVVUUUUUUUUUUUUUUUVVVVVVUUUVVVUUUTTTUUUTTTTTTTTTSSSTTTSSSSSSSSSVVVWWWUUUQQQIII;;;244/11244;==ACCGIIJLLKMMNNNMMMMMMLLLLLLOOOMMMLLLMMMNNNNNNMMMMMMNNNLLLKKKKKKLLLLLLJJJJJJIIIEEE???777222---***)))+++***&&&######(((***------,,,///000000222333333444333222333<<;C85<0-4/+2)%,.(/JJHKKKJJJJJJJJJKKKJJJLLLMMMKKKLLLLLLMMMNNNMMMMMMNNNOOOOOOMMMQQQMOOLNNNPPNPPNPPNPPPPPQQQQQQQQQQQQQQQRRRRRRRRRRRRRRRRRRRRRSSSTTTTTTTTTTTTSSSSSSTTTUUUUUUUUUTTTTTTTTTTTTTTTUUUUUUUUUSSSTTTWWWWWWVVVVVVWWWVVVVVVUUUUUUVVVWWWWWWUUUUUUVVVWWWWWWUUUVVVWWWVVVTTTTTTUUUTTTTTTUUUVVVUUUWWWWWWVVVTVVUWWTVVUWWWWWWWWWWWWWWWWWWWWXXXWWWUUUXXXVVVVVVWWWUUUUUUUUUWWWVVVVVVVVVVVVVVVVVVWWWUUUUUUUUUVVVWWWVVVVVVUUUUUUTTTWWWVVVTTTVVVVVVVVVVVVWWWWWWWWWUUUVVVUUUUUUTTTTTTTTTTTTTTTSSSTTTTTTTTTTTTTTTXXXYYYWWWMMMEEE888111333888BBBJJJOOONNNPPPOOONNNMMMOOONNNOOOPPPOOOOOONNNOOOOOOOOOMMMLLLMMMKKKJJJLLLMMMLLLHHHBBB999111---,,,,,,---,,,(((""" &&&+++,,,---...///222111222333444555666333222888FFFXXXeeeiiiiigeecggelljnnlqqossquusyyw}}{~~|}}{~~|€€~}}{zzx}}{ƒƒ‰‰…ŽŽŠœš”¬ª¤¸¶°º¸²¯­§žœ–­©£¥¡›¡—¡—Ÿ›•¡—£Ÿ™ œ–¤˜¥ž™§ ›¨¡œª£ž®§¢ª£ž¬¥ ­¦¡°©¤¯¨£°©¤¯«¥¯«¥¯«¥¯«¥³¯©³¯©²®¨µ±«·³­¶²¬¶²¬»·±º¸²¸¶°qrtJKMLJN315=;??=AA?C3154+3.%-1&.JJHJJJJJJKKKKKKKKKKKKMMMLLLLLLLLLLLLMMMMMMMMMMMMMMMNNNNNNOOOOOOMOOMOONPPNPPMOONPPOOOQQQQQQRRRPPPQQQRRRRRRRRRSSSRRRSSSSSSTTTSSSRRRRRRUUUSSSSSSTTTTTTTTTTTTSSSTTTTTTUUUTTTTTTUUUTTTUUUUUUUUUUUUVVVVVVWWWVVVVVVVVVWWWVVVVVVWWWUUUUUUVVVUUUVVVUUUVVVWWWWWWVVVVVVVVVTTTUUUVVVUUUUUUVVVXXXVVVUWWTVVTVVTVVVVVVVVTTTWWWXXXVVVWWWVVVWWWUUUVVVVVVVVVUUUUUUVVVWWWUUUUUUUUUVVVVVVVVVUUUVVVVVVUUUVVVUUUVVVVVVTTTUUUUUUUUUUUUVVVWWWUUUTTTVVVVVVUUUUUUWWWVVVVVVUUUUUUVVVUUUUUUUUUSSSSSSTTTSSSUUUUUUSSSUUUUUUTTTUUUXXXYYYVVVMMM@@@888444999AAAKKKPPPRRRQQQOOOPPPPPPOOOOOOOOOOOOOOOOOOPPPOOOOOONNNNNNLLLMMMNNNLLLMMMOOOMMMHHHBBB999111...---...///...)))!!!%%%)))---111111000000222333444444555555333000000===PPNaa_iigggehhfiigiigkkinnlrrpuusyywzzxzzxyywxxvzzx~~|}„„€†„~‡…ŒŠ„”’Œ‹…„‚|¨¤ž œ–œ˜’™•œ˜’œ˜’›—‘˜”ŽŸ˜“£œ— ™”¢›–¤˜¦Ÿš§ ›ª£žª£ž«¤Ÿ«¤Ÿ«¤Ÿ¨¤ž¬¨¢®ª¤®ª¤¯«¥¯«¥±­§´°ªµ±«´°ª´°ª¼¸²®¬¦omgKLNLMO:8<204<:>=;?A?C537.%-,#+6+3KKIJJJJJJLLLJJJKKKMMMIKKKMMLLLLLLLLLMMMMMMMMMMMMMMMOOONNNOOONNNLNNLNNMOOMOOMOONPPOOOPPPQQQQQQRRRQQQQQQRRRRRRRRRRRRSSSSSSSSSTTTSSSSSSTTTSSSSSSTTTTTTTTTRRRTTTUUUWWWUUUUUUUUUUUUVVVUUUVVVUUUVVVUUUVVVUUUVVVVVVUUUVVVWWWVVVVVVVVVVVVVVVVVVWWWVVVVVVVVVXXXVVVVVVVVVUUUUUUUUUUUUSUUSUUTVVSUUTVVSUUTVVUWWSUUSUUSUUTVVTVVRTTVVVVVVVVVVVVUUUWWWUUUTTTVVVVVVTTTUUUUUUVVVUUUUUUUUUTTTUUUTTTUUUTTTTTTUUUTTTTTTUUUUUUVVVUUUUUUVVVVVVVVVVVVUUUUUUTTTVVVVVVUUUVVVUUUVVVWWWVVVWWWVVVVVVVVVSSSUUUVVVVVVUUUTTTTTTSSSTTTUUUUUUTTTWWWYYYXXXUUUIII===888666>>>GGGLLLQQQSSSRRRQQQPPPPPPQQQPPPPPPOOOPPPQQQPPPOOOQQQOOOMMMNNNMMMLLLLLLLLLLLLHHH@@@<<<333222111111111000+++"""!!!'''...111222111222222222444444444553331220220997LLJ\\Zhhfiighhfggeiiglljoomrrpssquuswwuxxvzzx{{y||z|}y}~z~~z€€|vwsRSO““ŒŒˆ’Š’Š–’Œ•‘‹’Žˆ“‰–’Œ™•š–žš”¡š•£œ—£œ—¥ž™§ ›¥ž™¨¡œª£ž¬¥ ­¦¡¨¤ž¨¤ž­©£­©£¯«¥²®¨±­§´°ªµ³­¤¢œUTVLKM==AFFJ7/4=5:JGKJGK204.,0,!)=2:3&0JJHIIIKKKKKKKKKLLLKKKJLLJLLJJJLLLNNNNNNLLLMMMNNNNNNOOOOOOPPPOOOLNNLNNMOONPPMOONPPNNNOOOPPPQQQPPPPPPQQQSSSRRRRRRTTTRRRRRRSSSRRRSSSSSSTTTSSSRRRUUUTTTTTTTTTTTTUUUUUUUUUTTTUUUTTTTTTTTTTTTVVVVVVUUUVVVUUUVVVVVVUUUVVVVVVVVVVVVUUUWWWVVVVVVWWWVVVUUUVVVVVVVVVUUUTTTVVVVVVWWWVVVSUUTVVTVVSUUTVVTVVTVVUWWTVVSUUTVVSUURTTSUUUUUUUUUUUVVVUUUSSSSSSSSSRRRSSSSSSSSSSSSRRRSSSRRRSSSSSSTTTSSSSSSRRRTTTSSSRRRRRRSSSSSSRRRQQQQQQRRRSSSSSSTTTTTTRRRTTTUUUTTTTTTTTTUUUVVVVVVVVVVVVXXXXXXWWWVVVVVVWWWXXXXXXTTTVVVUUUVVVXXXWWWVVVWWWUUUVVVXXXYYYYYYZZZXXXRRRFFF;;;777999AAAIIIRRRTTTSSSQQQPPPPPPPPPPPPPPPPPPPPPPPPPPPNNNOOONNNMMMLLLKKKLLLKKKMMMMMMFFF???;;;555444333444555331--+###$$$,,,00022211122233344444244244255311/00.//-220BB@XXVffdkkikkiiigiigjjhmmkppnuusvvtvvtwwuvwsvwsxxtssoklh?@<\\X{‘‰‹…‰ƒŒˆ‚Š†€‹‡‰ƒ‹…Œ†“‰˜‘Œ™’›”ž—’Ÿ˜“ ™”©¢£œ—¥ž™§ ›§£¨¤ž«§¡«§¡­©£¯«¥¯«¥µ±«‡IGABACCBD55977;3+07/4;83;- *JJHJJJJJJKKKKKKLLLMMMLLLKKKLLLLLLMMMMMMLLLKKKMMMOOOPPPNNNNNNOOOOOONNNMOONPPMOOMOONPPMOOQQQOOOPPPQQQRRRRRRRRRRRRQQQRRRRRRTTTSSSSSSUUUSSSTTTTTTUUUTTTSSSSSSTTTTTTTTTVVVVVVTTTTTTUUUUUUTTTUUUVVVVVVVVVVVVUUUVVVVVVVVVVVVVVVUUUVVVVVVVVVVVVUUUUUUWWWWWWVVVUUUTTTUUUUUUUUUVVVUUUTVVTVVTVVUWWUWWXZZWYYWYYWYYVXXUWWSUUSUURTTQSSRTTSSSSSSQQQQQQOOONNNPPPPPPOOOOOOPPPPPPPPPOOOOOOPPPQQQPPPPPPPPPOOOPPPOOOOOOOOONNNNNNNNNOOOOOOOOOOOOPPPOOOOOOPPPQQQQQQQQQSSSSSSTTTUUUWWWWWWVVVWWWWWWXXXXXXXXXXXXXXXXXXXXXWWWVVVWWWXXXYYYXXXXXXVVVXXXXXXWWWXXXXXXXXXXXX[[[\\\WWWNNNCCC999999>>>GGGNNNSSSTTTRRRRRRRRRPPPPPPPPPOOOMMMNNNNNNLLLLLLMMMKKKLLLKKKJJJKKKJJJHHHDDD>>><<<888666777888777444...###!!!'''...00044433322244433300.220220220//-,,*,,,;;;QQObb`jjhjjhiighhfiiglljnnlssqqqoqqonnliigddbAA?IIGWWU‚‚~‹‹‡‹‡‰……{‡ƒ}Š†€Œˆ‚ŽŠ„Œ†’Žˆ˜“–‘Žš–™“ž—’œ•¡—¢ž˜¥¡›¤ š§£¨¤ž¨¤ž­©£©¦¤ligDAE748LFK@:?<58<58/(+703947:58213(')8,45)11$.JJHLLLLLLJJJKKKLLLLLLMMMMMMLLLMMMLLLLLLLLLNNNMMMNNNNNNOOOOOONNNOOOPPPNPPNPPMOONPPMOOMOOQQQPPPQQQQQQRRRQQQRRRRRRRRRRRRRRRRRRRRRRRRTTTTTTUUUUUUSSSSSSTTTUUUTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUTTTVVVWWWVVVUUUUUUWWWWWWVVVVVVVVVVVVVVVUUUVVVUUUUUUUUUVVVUUUSSSRRRRRRTTTTTTTTTSSSTTTRTTRTTSUUOQQ=??IKKQSSRTTRTTTVVUWWRTTOQQNPPNPPOQQPPPQQQRRROOONNNPPPPPPPPPNNNNNNOOOMMMMMMNNNNNNNNNNNNOOOMMMOOOMMMMMMMMMNNNMMMMMMNNNMMMMMMMMMMMMNNNOOONNNNNNNNNOOONNNOOOOOONNNOOOPPPSSSTTTUUUUUUVVVVVVVVVXXXXXXVVVYYYXXXWWWXXXYYYXXXXXXYYYYYYYYYWWWXXXXXXYYYYYYYYYXXXXXXXXXZZZZZZ[[[^^^]]]TTTJJJ???777666>>>HHHQQQTTTRRRPPPOOONNNNNNNNNNNNMMMLLLLLLKKKJJJIIIJJJJJJIIIHHHGGGGGGGGGCCC???;;;::::::999;;;<<<775..,!!!###)))...000111//-11/00.11/00...,---+++''%))'442GGE]][hhfiigeeceecffdeeceecddb``^[[Y==;KKIJJH__[}ƒyŠ†€‚~x}wƒy„€z†‚|‡ƒ}Š†€‹‡Ž‰†‘Œ‰”Š“‰˜‘Œœ•›—‘žš”žš”¡—£Ÿ™¤ š«§¡¬¨¢ligEB@:7;C@DA;@605<58:36-&)3,/50361498:2136*2/#+1$.JJHKMMHJJJJJKKKIKKJLLKKKLLLNNNMMMMMMLLLLLLMMMNNNOOONNNNNNNNNNNNOOOOOONPPMOONPPNPPOQQPRRPPPQQQPPPRRRRRRRRRQQQQQQRRRSSSRRRTTTRRRQQQSSSSSSTTTTTTTTTTTTUUUSSSTTTTTTVVVUUUSSSUUUUUUUUUUUUUUUUUUUUUUUUVVVVVVVVVVVVVVVVVVVVVUWWUWWUWWTVVUUUWWWUUUUUUVVVUUUSSSRRRSSSRRRRRRRRRTTTSSSPRRQSSPRRNPP:<>><<<;;;===>>>===888---!!%%%***///...---,,,+++**())'((&''%''%''%&&$,,*<<:RRPaa_ddbaa_^^\\\ZXXVLLJ==;HHFMMKOOMZZXkkgxxt}zw}zw~{x~{x~{x|y†~Š…‚Œ‡„Š…‚Ž‰†‹ˆ’Š–‘Ž”Šš–™•™“Ÿ›•¥¡›ŸœšgdbJHS75@E9C:.84(.;/5=173'-.$)0&+2+.A:=./1+,.2&,1%+-!'JJHIKKIKKJJJLLLKMMJLLLLLLLLLLLMMMMMMLLLMMMLLLLLLOOONNNMMMNNNNNNPPPPPPMOONPPNPPNPPOQQOQQPPPOOOQQQRRRRRRRRRRRRRRRRRRRRRRRRRRRTTTRRRTTTTTTSSSTTTTTTUUUTTTUUUTTTTTTUUUTTTUUUUUUUUUTTTVVVUUUWWWUUUUUUVVVVVVVVVVVVVVVUUUVVVUWWUWWTVVTVVUUUWWWVVVVVVVVVTTTSSSSSSRRRRRRRRRQQQQQQQQQPRRPRRPRROQQ:<997FFDIIGKKIGGEZZViiewtq{xu{xuyvsyvsyvs{vs€{xƒ~{„|Œ‡„‰„Ž‰†ˆ…•‘‹“‰•‘‹—“Ÿ›•žš”NKIFCA97B20;7+55)35)/9-39-34(.-#(-#(2+.:36,-/'(*+%4(.)#JJHIKKIKKLLLKKKIKKJLLLLLLLLKKKNNNMMMMMMMMMNNNNNNNNNMMMNNNNNNNNNNNNOOONPPNPPMOOOQQMOOMOOPPPPPPPRRNPPOQQPRRRRRRRRQQQSSSQQQQQQTTTTTTTTTSSSUUUSSSTTTUUUTTTUUUUUUTTTTTTTTTUUUTTTUUUTTTUUUVVVVVVVVVVVVVVVVVVWWWUUUWWWVVVVVVTVVSUUSUUSUUUUUWWWWWWVVVUUURRRTTTSSSQQQRRRRRRQQQQQQPPPOQQPRRPRRMOO:<????>>><:;:89:::;;;;;;777***$$$###%%%''''''&&&&&&&&&'''&&&%%%%%%%%%...777555@@@HHHGGGHHHIIILLJXXVfecpomqpnrqovspwtqwtqyvs|yv|yv€{xƒ~{…€}‡‚Š…‚Ž‰†Š‡“Ž‹“ŽEB@<:>;9==1;5)38)29*3;,5;,58*01#)."(/#)4*/D:?448((,* $4*..$(JJHHJJHJJKKKJJJIKKIKKKKKMMMKKKLLLLLLOOONNNMMMOOONNNOOOOOOMMMOOOPPPOOONPPNPPMOONPPMOONPPPPPOOONPPOQQOQQPRRRRRRRRRRRRRRRRRSSSSSSTTTTTTSSSSSSSSSSSSUUUUUUUUUVVVUUUUUUUUUUUUUUUUUUTTTTTTUUUVVVTTTTTTVVVVVVVVVWWWUUUTTTUUUTVVSUUSUUSUUUUUVVVUUUUUURRRRRRRRRRRRRRRRRRPPPQQQSSSRRRNPPOQQOQQLNN;==OQQOSTMQRLPQKOPMQRQUVMQRKOPNOQNOQMOONPPPPPOOOPPPOOONNNMMMMMMPPPNNNNNNNNNMMMLLLMMMMMMMMMMMMMMMNNNKKKLLLLLLLLLMMMLLLKKKKKKLLLLLLLLLKKKLLLLLLMMMMMMNNNMMMLLLMMMMMMKKKKKKLLLLLLMMMMMMOOONNNRRRVVVWWWWWWVVVWWWWWWXXXWWWXXXXXXYYYZZZZZZZZZ[[[XXXXXX[[[\\\ZZZ[[[[[[ZZZ\\\[[[\\\\\\\\\\\\[[[[[[\\\\\\ZZZYYYYYYYYYXXXWWWWWWXXXXXXXXXXXXSSSKKKBBB666444666>>>FFFIIIIIIHHHHHHIIIIIIGGGGGGHHHGGGEEEDDDDDDDBCDBCBBBAAA?=><:;;;;999999999,,,777555111''%  """$$$%%%%%%%%%&&&%%%333??????DDDGGGIIIJJHKKIVUSa`^jigqpnspmroltqnurourovsp{vs}xu}xu„|ˆƒ€‡‚‰„”Œ]ZX7422044266*48,68)27(13$-7(16(.2$*0$*3'-5+0:05115**.& (":04JJHKKIJJHJJJJJJLLLMMMKKKLLLKKKLLLMMMOOOMMMLLLNNNOOONNNNNNNNNOOOOOOOOONPPNPPMOONPPNPPPRROQQPRRPRROQQPRRPRROQQOQQPRRPRRSSSSSSSSSSSSSSSSSSSSSTTTUUUSSSTTTTTTVVVUUUTTTUUUUUUUUUVVVTTTVVVVVVWWWUUUUUUUUUWWWVVVVVVVVVTVVSUUTVVSUUSUUSUUUUUUUUVVVTTTRRRQQQQQQQQQSSSRRRQQQPPPQQQRRROQQOQQPRRLNN=>@OPRRVWOSTMQRLPQMQROSTMQRLPQOPROPRMNPMNPPPPOOONNNNNNMMMMMMOOONNNMMMLLLMMMMMMLLLNNNMMMLLLMMMLLLLLLLLLMMMLLLLLLLLLLLLLLLKKKLLLLLLKKKLLLLLLLLLKKKLLLMMMLLLLLLMMMLLLLLLLLLLLLLLLLLLMMMNNNPPPPPPSSSVVVXXXYYYXXXXXXYYYYYYXXXYYYYYYZZZ[[[[[[ZZZZZZZZZ[[[[[[[[[[[[[[[\\\\\\\\\[[[[[[\\\\\\\\\\\\[[[[[[ZZZZZZ[YZ[YZ[[[YYYWWWVVVVVVTTTTTTTTTUSTVTUUUUUUUOOOFFF<<<444664<<:EEEJJJLLLKKKIIIFFFGGGGGGFFFGGGECDFDEFDEDBCA?@@>??=>=;<<:;<:;...777444333000---((&!!!!!!!!!###&&&&&&&&&'''(((,,,555:::===BBBEEEGGGJJJJJJKKITTR_^\gfdmljnmkqnkpmjpmjspmwtquroxur}zw€{xƒ~{ˆ…d_\4/2:5863:2/62)10'/1(01(06'05&/1"+2#,2#,.(, (1%-,*.%#'' #(!$5+/JJHKKIJJHKKKKKKLLLLLLKKKMMMMMMLLLLLLMMMMMMMMMNNNNNNOOONNNNNNOOOOOOPPPMOONPPNPPMOONPPPRRPRROQQPRRPRRPRRPRROQQPRROQQOQQRRRTTTRRRRRRSSSRRRSSSSSSTTTTTTTTTTTTTTTTTTUUUUUUUUUTTTTTTUUUTTTWWWVVVUUUUUUVVVVVVVVVUUUTTTTVVUWWTVVRTTTVVTVVUUUTTTTTTRRRRRRQQQQQQRRRQQQRRRQQQPPPRRRQQQOQQOQQPRRJLL=>@PQSRVWQUVPTUNRSKOPOSTMQRMQRMNPNOQMNPMNPOOOOOOMMMMMMNNNNNNMMMMMMLLLLLLMMMMMMLLLNNNMMMLLLMMMMMMLLLLLLLLLMMMKKKLLLKKKLLLLLLKKKKKKLLLMMMLLLKKKKKKLLLKKKLLLMMMMMMMMMLLLLLLMMMLLLLLLLLLNNNNNNOOOOOOTTTWWWWWWXXXYYYYYYYYYYYYYYYYYY[[[\\\[[[ZZZ[[[[[[[[[ZZZ[[[\\\]]][[[\\\\\\\\\[[[[[[ZZZ[[[[[[[[[[[[[[[[[[ZXY[YZZZZYYYYYYWWWWWWWWWUUUTTTUSTTRSSSSQQQOOOPPPRRRSSSQQOIIG@@@===777:::@@@GGGIIIJJJIIIIIIHFGGEFFDEECDDBCB@AB@A@>??=>><=000888555333///---((&""  !!!$$$$$$%%%%%%&&&''''''))),,,222777888===@@@AAAEEEGGGIIIIIGLLJVUS]\Zdcafecjgdnkhpmjpmjolitqnurovspytq€{xqli4/,1,/:58307307/&.0'/2)1,#+4%.3$--'/ )+%,&-!), (0.2$"&' #%!+!%KKIJJHLLJJJHKKIKKKJJJLLLKKKLLLMMMMMMMMMMMMMMMLLLNNNOOONNNMOOMOOOOOPPPNPPNPPNPPMOONPPNPPOQQOQQPRRPRROQQPRRRRRRRRQQQRRRTTTQQQSSSRRRRRRSSSRRRTTTUUUTTTSSSSSSUUUUUUVVVTTTUUUVVVUUUUUUVVVUUUVVVVVVVVVVVVTVVTVVSUUSUURSUSTVSTVTUWTVVSUUUUUVVVTTTSSSRRRRRRRRRSSSRRRRRRPPPPPPQQQQQQOQQPRRNPPJLL<=?OPRRVWOSTMQRMQRKOPPTUNRSLPQMNPMNPNOQMNPOOONNNNNNNNNNNNNNNLLLMMMMMMMMMMMMLLLLLLMMMLLLLLLMMMMMMMMMKKKKKKLLLLLLLLLKKKKKKMMMKKKLLLMMMKKKLLLKKKKKKLLLLLLLLLMMMMMMLLLKKKLLLMMMMMMLLLMMMNNNNNNMMMMMMOOOWWWYYYYYYYYYYYYYYYZZZWWWXXXYYY[[[[[[\\\\\\\\\\\\[[[[[[\\\\\\\\\\\\]]]]]]^^^\\\\\\\\\\\\[[[[[[\\\\\\\Z[[YZZZZYYYYYYYYYWWWXXXWWWUUUVTUTRSSQRSQRRPQQOPQOPQOPPNOPNOQQQRRRQQQOOOFFF<<<:::999<<>>444999666333000---'''### !!!"""$$$%%%&&&%%%''')))******...222666999<<<>>>AAABBBDDDFFFHHHJJJLLJSSQ^][ba_fechgekhelifnkhlifnkhpmjvspwtq813+$&3+0:27228<?ASTVRVWPTULPQOSTLPQOSTNRSKOPOPRLMOLMOLMONNNNNNOOOOOONNNMMMNNNNNNNNNNNNMMMMMMMMMLLLMMMLLLMMMMMMMMMLLLLLLMMMMMMLLLKKKMMMLLLKKKMMMLLLKKKMMMMMMKKKKKKLLLKKKLLLLLLKKKLLLLLLLLLMMMLLLLLLLLLMMMMMMMMMMMMRRRYYYWWWXXXXXXYYYYYYZZZYYYZZZZZZ[[[[[[\\\\\\\\\[[[\\\]]]\\\\\\\\\]]]\\\]]]\\\\\\]]]]]]\\\\\\[[[\\\][\\Z[[[[ZZZXXXYYYXXXXXXVVVVVVWUVUSTUSTTRSSQRSQRRPQQOPQOPPNOPPPPPPNNNPPPOOONNNOOONNNJJJCCC:::777978?=>ECDGEFIGHECDBBBAAA555;;;999666111---)))$$$!!! """$$$$$$%%%&&&''''''(((***---000333777999;;;===AAABBBDDDFFFGGGHHHJJHLLJWVT_^\_^\ba_ifceb_ifchebjgdnkhvspFC@)"$,%'.&+:27339>>D*'+2/3407%!(4&38*72#-1",,))&+((%#&!&!(#$JJHIIGJJHKKIKKIIIGJJHKKKLLLKMMLNNLLLNNNLNNMOONNNNNNKMMMOOKMMLNNNNNPPPNPPMOOOQQOQQOQQOQQMOOOQQOQQOQQPRROQQOQQQSSRRRRRRRRRQQQRRRTTTSSSSSSTTTSSSSSSSSSSUURTTRTTRTTTTTUUUTTTUUUTTTTTTTVVSUUUUUVVVUWWSUUSUUTVVTUWRSUTUWTUWRSUSTVUWWRTTSUUSUUTTTTTTQPRRQSPOQQPRRRRRRRRRRRRRQQQPPPLNNMOOPQSHIK>>999666222...+++"""""" """%%%%%%%%%&&&'''(((***+++---111444777888;;;???@@@BBBDDDEEEEEEGGGIIIIIIMMKSSQZYW_^\^][_^\cb`dcaggcllh`][)&$.#')"(!$8149:B/084.53-41-4#&- *2%/-(/ *-(6'1'$- *)&+ ()$'"' #IIGHHFJJHJJHJJHKKILLJKKKKKKJLLJLLLLLNNNKMMLNNNNNMMMKMMLNNKMMKMMNNNOOOMOOMOOMOONPPNPPMOONPPOQQOQQOQQOQQQSSPRRPRRSSSRRRRRRRRRSSSSSSTTTSSSSSSRRRTTTTTTQSSRTTQSSRTTTTTTTTTTTTTTTTTSSSSUUTVVUUUUUUTVVSUUSUUSUURSURSUTUWTUWSTVTUWSUUSUUTVVTVVVVVUUURQSQPRPOQQPRPPPQQQPPPPPPQQQQQQMOOMOOLMOHIK=ABQUVQUVOSTLPQJNOHLMNRSLPQJNOLMOLMOJKMJKMLLLMMMOOONNNMMMNNNMMMMMMLLLNNNMMMMMMNNNMMMMMMNNNMMMMMMLLLMMMLLLMMMNNNLLLLLLMMMMMMLLLLLLMMMKKKLLLLLLLLLLLLLLLLLLKKKKKKMMMKKKLLLLLLLLLLLLLLLLLLMMMLLLLLLMMMLLLOOOUUUWWWXXXXXXXXXXXXYYYYYYZZZZZZ[[[[[[\\\\\\\\\\\\]]][[[[[[\\\[[[[[[\\\\\\\\\\\\\\\[YZ\Z[\Z[\Z[[YZ[YZZZZXXXWWWWWW[YZXVWYWXXVWVTUVTUVTUSQRSQRSQRRPQSQRRPQQOPRPQPNOQOPQOPOMNOMNMMMMMMNNNMMMMKLMKLKKKMMMLLLLLLLLLFFF888000+++111333888444111+++!!!%%%""""""$$$&&&&&&''')))***,,,---///222555666888;;;===???@@@BBBCCCEEEGGGIIIJJJKKINNLTSQWVT\[Y^][a`^cb`bb^iieC@>$!+ $/$(+$'6/223;#$,718/)0.*1#&+(/",*%-(.).)'$*'%",!)&!'"*#&IIGHHFJJHJJHKKIHKHHKHJJJLLLIKKJLLKMMLNNJLLKMMLNNLNNKMMLNNOOOMMMNNNNNNOOOOOOOOOPPPQQQPPPNPPNPPOQQOQQNPPPRRRRRRRRSSSSSSSSSRRRRRRSSSTTTSSSTTTVVVSSSTTTSUUSUURTTRTTUUUSSSTTTTTTUUUUUUSUUSUUVVVUUUTVVTVVRTTUWWSTVSTVTUWTUWTUWTUWUVXSTVTUWUVXWVXTSUTTTRRRQPRQPRQQQRRRRRROOOQQQPPPOQQMOOMNPIJL?@BQRTOSTNRSMQRJNOIMNMQRKOPIMNLMOLMOKLNJKMLLLMMMOOOMMMLLLLLLMMMMMMMMMMMMMMMMMMMMMNNNMMMMMMLLLMMMMMMLLLMMMMMMLLLLLLMMMLLLLLLLLLMMMMMMLLLLLLLLLKKKKKKKKKKKKKKKLLLKKKLLLLLLKKKKKKKKKKKKMMMLLLKKKLLLLLLMMMNNNPPPSSSXXXYYYXXXXXXXXXYYYZZZ[[[[[[\\\[[[\\\]]]\\\\\\\\\]]]]]]\\\\\\]]]\\\[[[\\\ZZZ[[[[[[\\\\\\[[[[[[ZZZYYYZXYYWXXVWYWXXVWWUVUUUSSSUSTSQRRPQTRSRPQQOPSQRRPQQQQPPPQOPQOPOMNPNOPNOOMNOMNPNOOMNNLMNLMMKLJJJJJJIIIHHHIII@@@@@@===666000,,,(((%%%$$$###""""""&&&'''((('''***+++,,,...000444555666999999<<<>>>???@@@DDDEEEFFFGGGJJJKKKKKKOOMRRPXWU[ZX[ZX]\Z_^\a`^1*,' "+!%& %!*#&)"%&")"%)"%.'*' #+!&* %(#&!)%($"!'&$#'!&'&%$$!$IIGHHFHHFJJHIIGILIILIKKKKKKIKKJLLKMMKMMKMMMOOLNNKMMKMMJLLNNNNNNMMMOOOPPPNNNPPPOOOOOOQQQMOONPPOQQOQQNPPOQQSSSRRRRRRRRRSSSSSSQQQRRRSSSTTTRRRSSSTTTSSSSUUSUUSUUTVVTTTUUUUUUUUUUUUTTTSUURTTUUUUUUSUUSUUTVVUWWSTVTUWSTVSTVUVXSTVSTVSTVSTVSTVUTVUTVUUUUUUTSURQSQQQPPPPPPQQQPPPPPPNPPNPPOPRHIK>?ARSUNRSMQRNRSNRSNRSOSTKOPJNOJKMKLNLMOLMONNNMMMMMMMMMLLLKKKJJJLLLLLLNNNMMMLLLMMMMMMLLLMMMMMMMMMMMMLLLKKKLLLKKKLLLMMMLLLMMMMMMLLLNNNLLLLLLLLLLLLLLLLLLKKKLLLLLLLLLLLLLLLKKKJJJKKKJJJLLLMMMKKKLLLLLLMMMMMMNNNNNNQQQUUUXXXXXXXXXYYYZZZZZZZZZZZZYYY\\\[[[[[[\\\]]]\\\]]]\\\]]]]]]\\\\\\\\\YYYZZZZZZYYYZZZ[[[ZZZZZZWWWYWXXVWWUVWUVWUVVTUTTTSSSSQRRPQRPQSQRQOPRPQRPQQOPRRRQQQQOPQOPRPQPNOPNOPNOPNOPNOOMNPNOPNONLMKKKKKKIIIHHHHHH222???>>>:::888888444'''###""" ###&&&'''((()))+++,,,---000111333555777777999<<<===???@@@CCCCCCCCCFFFHHHHHHIIIKKIMMKRQOUTRXWUWVT^][MLJ.')% %'!' #' #*#&*#&)"%$ +$'+$''"'"&!(#($+''&*!))#($#,#+! IIGJJHIIGJJHJJHLLJKKIIKKIKKIKKKMMJLLKMMMOOKMMJLLKMMLNNJLLMOOLNNNNNOOOOOOOOOQQQQQQOOOPPPOOOQQQQQQQQQOQQOQQQQQQQQPRROQQPRRPRRRRRQQQSSSSSSTTTTTTQSSQSSRTTQSSSUUTVVSUUQSSRTTRTTSUURTTRTTRTTRTTSUUSUUTVVRTTSUURSURSUSTVTUWTUWSTVSTVSTVSTVSTVSTVTUWUUUUUUUTVSRTRQSPOQQQQPPPPPPPPPNPPNPPMNPEFH<>>SUUNRSMQRLPQNRSPTUPTUMNPKLNKLNJKMJKMMNPNMONMOMMMNNNMMMMMMKJLLKMLKMLKMKKKJJJKKKKKKLKMMLNMLNMLNMMMMMMMMMLLLLLLLLLMMMLLLMMMLLLLLLLLLLLLKKKLLLLLLLKMLKMLLLLLLLLLLLLLLLLLLKKKKKKLLLKKKLLLLLLKKKKKKLLLLLLKKKMMMOOOQQQQQQTTTWWWXXXXXXYYYYYY\\\[[[[[[[[[[[[[[[[[[\\\\\\\\\[[[[[[[[[]]]]]]]]][[[[[[XXXXXXYYYZZZ[[[YYYYYYXXXWWWVVVVVVWUVVTUTRSTRSSQRSQRSQRRPQRPQRPQSQRRPQQOPQOPQOPQOPRPQQOPQOPQOPRPQRPQPNOQOPPNOQOPNLMNLMLLLIIIKKK666BBB===;;;888777444+++### ###$$$&&&((()))++++++---///111222444666888777:::<<<<<<@@@@@@@@@DDDCCCEEEHHHHHHHHHJJJKKKMMKRRPSRPVUS]YZ/+,+$&% %!%!$)"$) "+"$)#%0&*+!%& '!)"%$ (".$(%!(*&-+(/# '&")'#*# 'HHFJJHIIGIIGJJHKKIKKIIKKKMMJLLIKKIKKJLLIKKJLLKMMLNNLNNKMMLNNLNNOOONNNPPPNNNOOOOOOPPPPPPPPPPPPRRRQQQOQQOQQQQQQQQPRRPRRPRRPRRRRRQQQQQQRRRSSSSSSRTTRTTRTTRTTRTTRTTSUUQSSRTTQSSQSSSUURTTRTTRTTRTTRTTTVVRTTRTTSTVTUWSTVSTVRSURSUSTVSTVRSUSTVSTVRSUUUUTTTTSURQSQPRPOQQQQPPPOOONNNMOOMOOMNPEFH;==QSSPTUOSTNRSKOPLPQMQRMNPKLNJKMJKMKLNKLNNMONMOMMMMMMMMMMMMMLNMLNLKMMLNKKKIIIJJJIIIJIKKJLIHJIHJJJJKKKLLLLLLLLLLLLLLLMMMKKKKKKLLLKKKKKKLLLLLLLLLLKMKJLLLLLLLKKKLLLKKKKKKKKKKKKKKKLLLKKKJJJKKKKKKKKKJJJKKKLLLMMMNNNOOORRRUUUWWWXXXZZZZZZ[[[ZZZZZZ[[[YYYZZZ[[[[[[[[[\\\\\\ZZZZZZ[[[[[[YYYZZZ[[[ZZZXXXYYYXXXZZZZZZXXXXXXWWWUUUTTTUSTTRSTRSSQRSQRSQRSQRSQRQOPQOPRPQQOPQOPRPQRPQPNORPQSQRQOPQOPRPQSQRRPQQOPOMNPNOPNONLMKKKKKKMMM:::BBB@@@>>>:::777333...'''&&&%%%&&&''')))+++,,,...000000333555666888888999;;;<<<>>>??????AAACCCDDDEEEEEEGGGHHHIIIJJHKKIONLTSQPLM'#$)"$% &"%!"% %&(")#("'!%%(!$&"("+!%$ ')%,(%,#$ '$!(JJHHHFIIGKKIJJHKKIKKIMMMKKKHJJIKKJLLKMMJLLJLLJLLKMMNNNNNNMMMNNNOOOOOOOOOPPPOOOOOOOOONNNMOOOQQNPPNPPNNNQQQQQQPPPQQQQQQQQQRRRRRRRRRRRRRRRSSSSSSPRRPRRPRRRTTPRRRTTRTTQSSTTTSSSSSSTTTRTTSUUSSSSSSSSSTTTRTTSUUSTVTUWSTVRSURSUSTVRSURSUSTVRSUUTVSRTSRTTSUTSUQPRONPPOQRRROOOOOOOOOMOOLNNNOQBCE8::?AACDFHIKIMNJNOMNPNOQKLNKLNKLNLMOJKMKLNLNNKMMJLLKMMKLNKLNKLNKLNLKMLKMLKMLKMKJLLKMJIKKJLIHJHGIGFHHGIIHJHGIKJLIHJFEGHGILKMMLNLKMLKMLKMLKMLKMKJLKJLLKMKKKKKKKKKKKKLLLKKKKKKKKKKKKJJJIIIKKKLLLLLLJJJJJJKKKLLLMMMLLLMMMOOOPPPSSSXXXXXXYYYXXXYYYXXXYYYXXXYYYYYYZZZ[[[ZZZ[[[ZZZZZZZZZXXXYYYYYYYYYZZZXXXXXXWWWWWWWWWVVVWWWVVVTTTSSSUSTUSTSQRRPQSQRRPQRPQSQRQOPRPQRPQRPQSQRRPQRPQSQRSQRRPQRPQRPQSQRSQRRPQQOPQOPPNOPNOOMNNLMMKLOOO;;;EEEBBB>>><<<888555000+++''''''(((&(((***,,+--,...00/11022444555666888999::::::===???>>>@@@BBBCCCEEEFFFFFFHHHIIIIIIIIILJKRPQ623$ !&"#$ !  $$$(!#+"$) "$) ".')(!##,%'--3%%+#%+%!' "(!'IIGIIGIIGJJHJJHJJHKKIKKKJJJIKKIKKJLLJLLJLLJLLJLLKMMOOONNNNNNNNNOOONNNOOOOOOPPPOOOPPPOOOMOOMOONPPNPPPPPPPPOOOPPPOOOQQQOOOPPPQQQQQQQQQRRRRRRRRRPRRPRRPRRQSSQSSPRRPRRQSSSSSSSSRRRTTTRTTQSSTTTTTTSSSSSSQSSRTTRSUQRTRSUQRTRSUSTVQRTRSUQRTQRTSRTRQSSRTQPRQPRONPPOQPOQOOOOOONNNNNNMOOMOOLMOLMOEGGACC@AC>?A;>@9<>ABDKLNLMOMNPLMOKLNKLNLMOKMMJLLJLLJLLKLNKLNJKMKLNMLNLKMMLNMLNMLNLKMKJLKJLLKMKJLIHJHGIGFHGFHGFHFEGDCEEDFKJLKJLLKMLKMKJLLKMLKMKJLLKMKJLJJJKKKJJJJJJJJJKKKLLLJJJKKKJJJJJJLLLKKKKKKJJJJJJIIILLLMMMLLLMMMMMMNNNQQQVVVYYYXXXYYYYYYYYYYYYZZZZZZYYYYYYYYYYYYZZZZZZZZZYYYXXXYYYYYYXXXXXXXXXWWWWWWWWWWWWVVVWWWWWWUUUTTTTRSRPQSQRUSTTRSRPQSQRRPQRPQRPQRPQQOPRPQRPQSQRSQRSQRRPQRPQRPQSQRSQRSQRRPQRPQRPQRPQOMNOMNOMNOOO>>>DDDBBB>>><<<888666000***(((((()))(**)++*,,-//,...00133244555777777888888:::<<<<<<>>>???@@@AAADDDFFFFFFGGGGGGGGGHHHJJJKIJMKL$ !# )%&'#$ (!#"&!(!#%&#+"$0)+' "#0)+..4%%+$&,!#) "(+-3 &JJJIIIIIIJJJKKKJJJKKKKKKLLLIKKIKKJLLJLLKMMJLLJLLKMMKMMLNNMMMNNNOOONNNNNNOOOQQQOOOLNNLNNNPPMOOMOOMOOOOOOOOQQQPPPOOOOOOPPPQQQRRRPPPRRRQQQQQQQQQOQQPRRQSSPRRQSSOQQRRRSSSRRRSSSRRRRRRRRRRRRSSSSSSRRRRRRRRRRRROQQQSSPRRPRRSRTRQSOPRPQSPQSPQSRQSQPRNOQMNPNOQNOQMNPLMOMNPLMOLMOLMONOQLMOMNPNOQMNPNOQOPRMNPJKMMNPLNNKMMKLNLMOLMOJKMKLNKLNKMMKMMKMMKMMKLNKLNKLNKLNKLNKLNKLNJKMJKMJKMIJLJKMLKMLKMLKMKJLJIKJIKKJLHGIIHJJIKKJLKJLKJLLKMLKMKJLKJLLKMJJJLLLJJJIIIJJJJJJJJJKKKJJJJJJJJJJJJIIIJJJIIIJJJIIIJJJKKKKKKLLLLLLLLLLLLLLLMMMPPPVVVXXXZZZZZZ[[[YYYYYYZZZYYYZZZZZZYYYYYYZZZYYYZZZZZZYYYYYYXXXXXXWWWWWWVVVVVVVVVWWWUUUUUUUUUTTTSSSSSSTTTRRRPPPPPPPPPPPPRRRQQQPPPQQQPPPRRRRRRSSSRPQRPQSQRSQRTRSTRSTRSSQRTRSRPQRPQRPQNNNMMMOOO===@@@DDD???>>>999888111,,,((((((***(***,,,..-//-///111332444664665776886889;;:::<<>>:::777222---)))(((***)+++--+---//.000221332443555775776887998:::::<<<===>>>>>>AAABBBCCCCCCDDDGGGEEEFFFGGGGGG### """""",,,! # "$$(!#####'#$"&"#'#$#'.*.5%'9)+=(-<-2A&*1FHHGIIHJJHJJGIIKKKJJJJJJKKKJLLIKKGIIJLLHJJIKKKMMJLLLLLLLLKKKKKKNNNNNNNNNOOONNNNNNMOOLNNMOOMOONPPNPPMOOPRROOOOOOPPPOOOPPPPPPPPPQQQQQQQQQPRROQQOQQPRRNPPNPPPRRPRROQQOQQRRRQQQSSSRRRQQQPPPQQQQQQPPPPPPOOOPPPPPPPPPOOOOOOONPONPONPONPNMOONPNMONMOLMOMNPLMOMNPLMOLMOLMOKLNKLNKLNLMOJKMKLNLMONOQLMOKLNKLNLMOLMOJLLKMMJLLKMMLNNJLLKMMKMMKMMKMMKLNKLNJKMJKMJKMIJLLMOKLNJKMJKMKLNJKMLKMLKMLKMLKMJKMIJLJKMIJLLKMLKMKJLJIKKJLKJLJIKKJLKJLKJLJIKJIKIHJIHJIIIJJJKKKIIIJJJJJJJJJIIIJJJJJJJJJIIIIIIIIIKKKIIIIIIJJJIIIIIILLLJJJKKKKKKMMMMMMNNNSSSXXXXXXXXXYYYXXXWWWVVVXXXYYYXXXXXXXXXYYYWWWWWWWWWWWWWWWVVVVVVUUUVVVTTTUUUTTTTTTSSSRRRRRRRRRQQQRRRRRRQQQPPPQQQQQQPPPQQQPPPQQQQQQQQQQQQSQRTRSSQRSQRSQRTRSSQRSQRTRSRPQRPQRPQQQQOOONNN666BBBGGGBBB???;;;666000///'))))),,,*,,+--+---///110221332442444665775777997998:::<<:<<;==@@@@@@???CCCBDDACCCBDDCEBCEGHJ89;!##"$$"""%%% # "%"  ! ! $"#"%(!$!&1',7H$$N#72 EGGFHHGIIGIIGIIJJJIIIJJJIIIIKKIKKGIIIKKJLLIKKIKKIKKLLLMMMLLLLLLMMMMMMMMMNNNNNNMMMLNNKMMLNNNPPMOONPPNPPNPPPPPOOOOOOQQQPPPPPPPPPOOOQQQRRRNPPNPPOQQPRROQQOQQOQQOQQOQQPRRSSSPPPPPPQQQOOORRRQQQOOOOOONNNNNNOOOOOOOOOPPPNNNNMONMOONPONPNMONMONMONMOMNPKLNKLNLMOKLNLMOLMOJKMJKMMNPKLNLMOLMOKLNLMOLMOKLNJKMKLNLMOJLLLNNJLLJLLKMMKMMJLLJLLKMMLNNJKMKLNKLNJKMKLNKLNJKMJKMJKMJKMJKMIJLLKMKJLLKMLKMJKMHIKIJLIJLLKMKJLKJLJIKJIKKJLJIKJIKJIKJIKJIKJIKJIKJIKJJJIIIJJJKKKIIIKKKJJJIIIIIIJJJIIIIIIHHHIIIJJJIIIHHHHHHIIIIIIIIIKKKKKKJJJLLLMMMMMMOOOUUUXXXWWWWWWXXXXXXWWWZZZYYYWWWWWWXXXXXXWWWXXXXXXWWWVVVVVVVVVTTTUUUTTTTTTTTTSSSRRRRRRSSSQQQQQQQQQPPPPPPPPPPPPQQQQQQQQQQQQQQQRRRQQQRRRSQRTRSSQRSQRTRSTRSTRSSQRTRSTRSRPQRPQOOONNNOOO:::FFFEEEBBB???<<<888111---(**)))***+---//,...00/110220222443555775776886888:::<<:<<;==:<<>>>>>>???BBBACCCEEBACDCEDEGIJL!"$&((###!!! !$!# ""# &$%,/2#&)!,,1< JD"6$8#FHHGIIGIIGIIGIIGIIGIIHJJHJJHJJIKKHJJIKKIKKIKKIKKIKKJLLJLLJLLJLLIKKJLLJLLLNNKMMKMMKMMKMMKMMMOOLNNLNNLNNMOONPPNPPNPPMOOPPPRRRNPPNPPOQQOQQOQQOQQOQQOQQOQQOQQOQQNPPRRRRRRRRROOOPPPPPPOOOOOONNNNNNNNNOOONNNPPPNNNMMMNMONMONMOONPNMONMOLKMNMONMOMLNNMONMONMOMLNKLNKLNKLNLMOJKMKLNKLNLMOKLNIJLJKMJKMKLNKLNKMMKMMLNNMOOKMMKMMKLNJKMJLLJLLKLNJKMJKMKLNJKMJKMKLNJKMHIKIJLKLNJKMJKMIJLJKMIJLJKMKLNIJLHIKIJLJKMIJLIJLIJLHIKKJLKJLIHJIHJIHJIHJJIKJIKIIIJJJJJJIIIJJJJJJIIIIIIIIIHHHIIIIIIIIIHHHIIIIIIIIIIIIIIIIIIHHHIIIJJJJJJIIIIIIKKKJJJKKKLLLOOOYYYVVVWWWWWWWWWWWWZZZWWWWWWWWWWWWWWWYYYXXXWWWVVVVVVWWWUUUUUUTTTSSSSSSRRRRRRRRRQQQPPPPPPPPPPPPPPPPPPPPPPPPOOOOOOPPPPPPRRRQQQQQQQQQRPQSQRRPQSQRSQRTRSSQRRPQTRSTRSRRRPPPPPPOOOQQQ777EEEEEECCC???;;;999022,..+++(**(***,,,..,...00/110220222443554665776886887998::7999;;<>>;===??@BB?AA>@@@BBABD@ACCCG66: #$&!!$' #& "$#!#" &$%"$1&(5)/@#4,(-:GD!(7!0#$FHHGIIGIIGIIHJJHJJGIIHJJIKKIKKIKKJLLIKKJLLIKKJLLIKKJLLJLLJLLKMMKMMKMMJLLKMMLNNKMMKMMKMMKMMMOOLNNMOOMOOLNNKMMLNNKMMMOOOOOPPPLNNLNNOQQNPPMOONPPNPPNPPMOOOQQNPPMOOPPPOOOOOOMMMNNNOOOMMMMMMOOOOOONNNNNNNNNNNNMMMNNNMLNMLNNMONMOMLNMLNLKMLKMMLNNMONMOMLNMLNNMOKLNKLNKLNKLNKLNJKMKLNKLNJKMJKMJKMJKMKLNMNPKMMJLLKMMKMMLNNKMMJKMIJLIKKJLLJKMJKMJKMJKMJKMJKMIJLKLNJKMIJLIJLIJLJKMIJLJKMIJLJKMIJLHIKJKMHIKIJLJKMJKMIJLIJLKJLJIKKJLJIKJIKIHJIHJIHJIIIJJJJJJJJJIIIJJJJJJHHHHHHHHHHHHIIIHHHGGGIIIIIIHHHIIIIIIIIIIIIIIIJJJIIIHHHIIIJJJKKKKKKKKKJJJNNNWWWWWWUUUWWWWWWXXXXXXVVVVVVVVVVVVVVVVVVUUUUUUUUUUUUUUUSSSRRRSSSSSSQQQPPPPPPQQQQQQQQQPPPOOOPPPOOOOOOOOOOOOOOOPPPPPPQQQQQQRRRSSSSQRUSTRPQSQRRPQSQRSQRSQRRPQSQRRRRPPPNNNPPPPPP444BBBFFFCCC@@@;;;888/11-//+++(**)++*,,,..-//.000221332442444665776886887997998::8::9;;<>>;==;===??=??>@@@BBABD@ACCCG#  "  #"%!"$  %#$"""&&&+-:+-:#):/+&+8GA#2."#EGGFHHFHHGIIGIIHJJHJJHJJHJJIKKIKKIKKIKKHJJIKKIKKJLLIKKJLLKMMLNNKMMMOOKMMKMMLNNLNNLNNLNNLNNMOOMOOMOONPPMOOLNNMOOMOOMOOPPPNNNNNNOOOLNNMOOMOOMOOKMMLNNMOONPPMOOMOONNNNNNOOONNNNNNNNNMMMMMMNNNMMMMMMLLLMMMMMMLLLMMMLLLMMMMMMLLLLLLMMMLLLLLLLLLNNNJKMJKMJLLJLLKLNKLNJKMKLNKLNKLNJKMJKMJKMIJLJKMJKMJKMKLNKLNJKMKMMJLLJLLJLLJKMKLNIKKIKKJLLJLLIKKIKKIKKJLLIKKJLLIKKIKKIJLIJLIJLIJLIJLJKMIJLHIKIJLIJLIJLHIKGHJIJLJIKIHJJIKJIKKJLJIKKJLIHJJIKJIKJIKJIKJJJJJJJJJJJJJJJHHHGGGHHHGGGGGGGGGHHHGGGIIIHHHHHHHHHIIIIIIIIIIIIIIIIIIJJJIIIJJJJJJJJJJJJJJJQQQWWWUUUVVVWWWUUUVVVVVVUUUVVVUUUUUUTTTTTTUUUUUUUUUSSSRRRRRRQQQRRRRRRPPPPPPPPPOOOPPPOOOOOOPPPNNNOOONNNMMMOOOPPPPPPRRRQQQQQQQQQRPQRPQRPQRPQSQRSQRSQRTRSUSTSQRRRRPPPOOOPPPPPP444>>>GGGCCC???<<<888111///)))(***,,*,,,...00/11/110222443553554665777997996889;;8::9;;:<<;==>@@<>>=??>?A=>@?@B?@B8;>!"!$#) &#&) %$&,$(.$%>#)B$*A3"-#)4+* #!&)""HJJGIIIKKIKKHJJHJJIKKKMMIKKHJJHJJHJJHJJIKKIKKIKKJLLJLLKMMJLLJLLKMMJLLLNNKMMKMMKMMKMMLNNLNNMOOKMMMOOLNNMOOMOONPPNPPMOOOOOPPPQQQQQQNPPMOONPPNPPNPPLNNNPPPRRNPPLNNNNNNNNNNNOOOOOOLLLNNNMMMNNNNNNMMMMMMLLLMMMLLLKKKLLLMMMMMMLLLLLLKKKKKKKKKLLLMMMJKMKLNJLLIKKJKMJKMJKMJKMJKMJKMKLNJKMKLNJKMJKMJKMJKMKLNKLNJKMJLLKMMKMMJLLJKMJKMIKKIKKHJJIKKIKKJLLJLLIKKIKKIKKIKKIKKIJLJKMIJLIJLIJLIJLIJLIJLIJLHIKHIKHIKGHJHIKIHJJIKIHJKJLJIKJIKJIKJIKIHJIHJIHJJIKJJJIIIIIIHHHHHHHHHGGGIIIIIIHHHGGGHHHGGGHHHIIIIIIIIIHHHHHHIIIIIIJJJIIIHHHHHHIIIIIIJJJIIIIIIJJJUUUUUUTTTVVVTTTVVVVVVUUUUUUUUUTTTSSSTTTTTTSSSSSSSSSRRRRRRQQQQQQRRROOOPPPPPPOOONNNNNNMMMNNNNNNNNNNNNOOOPPPPPPOOOQQQQQQPPPPPPSQRRPQSQRSQRTRSRPQSQRTRSSQRSQRRRRQQQPPPOOOPPP555???GGGAAA>>>;;;888222000)))(**)+++--,../11.001331332442443554665775775776888::8::9;;:<<;==;===??>@@>?A>?A=>@CDF$'*   %(+"&,"(!$!!"""%%%$&,%'-#) $*C&,E$*A6()+/!$=???AA?AAACCCEECEEEGGGIIHJJHJJIKKLNNKMMLNNKMMLNNLNNLNNLNNKMMLNNKMMLNNLNNLNNLNNLNNLNNLNNKMMLNNMOOLNNNPPLNNNPPNPPPRRNPPMOOMOONPPLNNNPPMOONPPOQQNPPMOONPPOQQMOOMOOMOOMOOOOONNNNNNOOONNNNNNMMMNNNNNNLLLMMMMMMMMMMMMMMMNNNLLLMMMMMMMMMKKKKKKJLLJLLJLLJLLJLLKMMJLLJLLIKKIKKJLLIKKJKMJKMJKMJKMKMMJLLJLLJLLJKMJKMIKKJLLKMMJLLJLLIKKIKKJLLJLLJLLJLLIKKHJJHJJIKKJLLJLLHJJIKKIKKIJLHIKHIKIJLHJJHJJHIKIJLHIKHIKHIKHIKHIKHIKIHJIHJIHJIHJJIKJIKHHHIIIHHHIIIJJJHHHHHHIIIIIIIIIIIIIIIGGGGGGHHHHHHGGGGGGHHHGGGGGGHHHHHHHHHIIIIIIHHHGGGGGGIIIHHHIIIJJJJJJIIIMMMRRRTTTTTTTTTSSSTTTSSSSSSSSSSSSRRRRRRRRRRRRRRRRRRRRRQQQQQQPPPOOOOOOPPPOOONNNNNNNNNNNNOOONNNMMMNNNOOOOOOPPPPPPOOOQQQPPPPPPQQQRRRRRRRRRSSSSSSRRRRRRRRRQQQOOOPPPOOOOOOPPP666<<<=?<=??@B??C77;!'#'-$+ '" %(!(+!$+#0$="*C '$*1N&C#80 $$##&((&((&((&(((**)++*,,,..*,,+--+--/112444663556889;;;==<>>>@@BDDACCDFFDFFFHHHJJJLLKMMLNNLNNMOONPPOQQOQQOQQQSSPRRPRRPRRNPPPRRMOOMOOMOOMOONPPNPPLNNMOOMOONPPMOOMOOMOOMOONNNMMMNNNNNNNNNMMMMMMMMMNNNMMMLLLMMMLLLLLLLLLMMMLLLLLLMMMMMMLLLLLLKMMKMMJLLKMMKMMJLLKMMJLLJLLJLLJLLJLLJKMJKMJKMJKMIKKIKKIKKJLLIJLHIKJLLJLLIKKJLLJLLJLLJLLJLLJLLJLLJLLIKKIKKIKKJLLIKKHJJIKKIKKHJJIJLHIKHIKIJLGIIIKKIJLHIKHIKHIKGHJGHJIJLHIKJIKIHJIHJIHJIHJIHJHHHHHHIIIIIIIIIHHHGGGIIIIIIIIIHHHGGGGGGGGGIIIIIIGGGGGGGGGHHHGGGGGGGGGHHHHHHGGGHHHIIIGGGGGGHHHJJJKKKJJJIIIJJJOOORRRRRRQQQSSSQQQRRRRRRQQQQQQQQQQQQRRROOOQQQQQQPPPOOOPPPPPPNNNNNNNNNNNNNNNMMMOOONNNNNNNNNMMMNNNOOOPPPQQQPPPPPPPPPOOOQQQQQQPPPQQQQQQRRRQQQPPPRRRRRRRRRPPPPPPOOONNNPPP999>>>DDDCCC???<<<777111///+++)++*,,,../11.00/111331333554665774665774664665777997998::9;;:<<:<<:;=;<><=?>?AAAE((,#)"&,$+#!$$),*/2#*-!&3$)6$=&?!( '!>: 5,!"!!?AA<>>:<<9;;8::799466133244022/11,..*,,)++)++)++(**(**'))&((&((%''&((&((')))++)++*,,,..-///111333556888::9;;<>>?AA@BBCEEBDDFHHIKKIKKJLLLNNMOOMOOOQQOQQNPPOQQPRRPRRPRRPRROQQQQQOOOOOOPPPPPPNNNNNNNNNOOOMMMLNNKMMMMMMMMLNNKMMKMMJLLKMMJLLIKKIKKJLLKMMKMMJLLKMMKMMKMMKMMKMMKMMLMOKLNJKMJKMJLLHJJIKKKMMKMMJLLJLLJLLJLLJLLKMMJLLKMMJLLIKKIKKHJJHJJKMMJLLIKKHJJIKKIKKHJJIKKGIIGIIGIIHJJHJJHJJHJJHJJHJJFHHGIIFHHGHJFGIFGIGHJGHJFGIGIIHJJJIKHGIHHHHHHHHHIIIIIIHHHIIIHHHGGGIIIHHHGGGGGGGGGGGGGGGGGGGGGGGGGGGFFFGGGFFFEEEGGGHHHHHHHHHGGGGGGGGGHHHIIIIIIKKKNNNPPPPPPQQQQQQQQQPPPOOOPPPPPPPPPPPPQQQQQQOOOPPPOOONNNNNNNNNMMMMMMNNNMMMNNNNNNMMMNNNMMMMMMNNNNNNOOOPPPPPPOOOOOOOOONNNQQQQQQPPPPPPQQQPPPQOPRPQRRRQQQQQQPPPOOOMMMNNN888>>>DDDBBB>>>9;;688/11-//,,,*,,+---//-///11/110222442443554664665775774666886887998::9;;9;;<>>;<>;<>;<>=>@?BE #!"%,%,$+"!,!)4'=(>#%#8#8"8#9$")!0!0!PRROQQPRRQSSQSSQSSRTTQSSRTTQSSQSSQSSQSSOQQOQQNPPKMMIKKIKKIKKDFFDFFDFFACC?AA;==9;;8::8::355244/11-//,..+--+--*,,(**(**(**'))&((&(('))(**)++)++*,,,..-//.001332443555778:::<<>>>AAAAAADDDEEEGGGIIIHHHLLLLLLLNNLNNMMMOOOMOOMOOOQQMOONPPMOOLNNLNNMOOMOOLNNMOOLNNKMMLNNLNNLNNJLLJKMKLNJKMJKMJLLJLLIKKJLLJLLJLLIKKJLLJLLKMMJLLKMMLNNJLLJLLIKKIKKJLLJLLIKKIKKIKKHJJIKKJLLHJJHJJHJJHJJFHHFHHHJJGIIGIIHJJGIIFHHGIIFGIFGIFGIFGIDEGEFHFHHFHHHGIHGIHHHGGGHHHIIIHHHHHHHHHFFFGGGHHHFFFGGGEEEFFFFFFFFFGGGFFFFFFFFFGGGGGGFFFFFFFFFHHHFFFGGGGGGGGGGGGGGGGGGHHHHHHKKKOOONNNOOOPPPOOOPPPOOONNNOOOPPPNNNOOOOOOOOONNNNNNMMMMMMNNNOOOLLLLLLMMMMMMLLLMMMLLLLLLNNNMMMLLLMMMOOONNNPPPNNNOOOOOOPPPPPPRRRQQQQQQPPPRPQRPQPPPQQQPPPNNNOOOMMMNNN777>>>EEEAAA>>>:<<577.00-//,,,*,,+--,../11/11/110220222443553555776886884664666886888::8::8::9;;:;=<=?:;=<=?58;  &#'-"(/#*$$'2 (3(>"8$#)#8#8#9 6!(!(#2$3!MOOLNNLNNNPPNPPNPPOQQPRRNPPQSSQSSQSSQSSRTTRTTTVVTVVUWWVXXTVVTVVUWWWYYWYYWYYWYYWYYWYYVXXWYYVXXTVVWYYUWWSUUTVVTVVQSSOQQMOOKMMIKKHJJFHHFHHBDD?AA;==:<<799577577244244/11.00)++)++)++*********(((%''&(())))))***,,,,,,....00/11244355577799;==:<<>@@@BBDFFDFFFHHGIIHJJKMMLNNLNNMOOMOOMOONPPMOOLNNLNNLNNMOOLNNLNNLNNLNNKMMJLLJLLMOOJLLKMMJLLKMMJLLJLLIKKIKKIKKIKKHJJIKKIKKIKKIKKJLLGIIHJJGIIGIIHJJHJJHJJGIIGIIGIIFHHFHHGIIFHHFHHEGGDFFEGGEGGGIIEGGFHHEGGDFFEGGEGGEGGGGGGGGEEEGGGGGGEEEFFFFFFGGGGGGFFFEEEGGGFFFFFFFFFEEEFFFFFFFFFFFFFFFFFFFFFGGGGGGHHHJJJMMMNNNNNNOOONNNOOONNNMMMNNNNNNMMMMMMLLLKKKMMMLLLLLLLLLLLLLLLLLLKKKKKKLLLKKKLLLLLLMMMMMMNNNMMMMMMMMMOOOOOOOOOOOOPPPOOOPPPPPPPPPPPPQQQRRROOOOOOOOOOOOOOONNNMMMOOO666;;;FFFAAA???8::466/11-//*,,)+++--,../11-///110221332443555555555776885775776886887998::8::9;;:;=;<>:;=>?A146 #&!2"(9"+ ) $&2%1%1 , &&,(7+:)=P':%*"'%"!HJJHJJIKKHJJIKKHJJJLLKMMIKKJLLJLLLNNLNNLNNNPPMOOMOONPPPRROQQPRRQSSQSSPRRQSSRTTRTTSUUSUUTVVTVVTVVUWWUWWUWWTVVVXXWYYWYYXZZY[[XZZY[[Y[[Z\\Z\\Z\\Z\\[]]\^^Z\\Y[[Y[[XZZWYYVXXVXXVXXVXXVVVTTTRRRPPPKMMJLLKKKHHHEEEAAA???===466244355133022.00-//)++)++(**'))&((&((&((&((&((&(((**+---//-//0223556889;;:<<>@@@BBBDDEGGEGGIKKIKKJLLKMMLNNMOONPPMOONPPOQQOQQNPPKMMLNNMOOMOOLNNIKKJLLJLLHJJIKKIKKHJJHJJGIIFHHEGGFHHGIIFHHFHHGIIGIIGIIEGGFHHFHHEGGFHHGIIFHHFHHFHHFHHFHHFHHGGGGGGGGGFFFGGGGGGGGGGGGFFFEEEGGGFFFGGGFFFEEEFFFEEEEEEFFFFFFEEEFFFFFFEEEGGGFFFFFFGGGIIIMMMLLLNNNMMMNNNMMMLLLMMMLLLMMMMMMKKKKKKLLLLLLKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKLLLJJJLLLLLLLLLLLLLLLNNNNNNPPPOOONNNOOOPPPOOOOOOOOOQQQPPPOOOOOONNNNNNMMMKKKNNN555888EEE@@@>>>9;;466.00.00*,,)+++---//.00.00022/111332444665556664665775775775774667997998::9;;:;=9:<9:<>?A%(*""%$5#4'%$#(#/ ,!-#/(.)5;&7F5FU*>Q$7#( %&%"" %""# ! EGGGIIGIIHJJGIIHJJHJJHJJHJJIKKIKKIKKIKKJLLJLLIKKIKKJLLJLLJLLKMMLNNKMMKMMMOOLNNKMMLNNMOOMOONPPNPPOQQOQQNPPNPPOQQPRRPRRQSSRTTRTTRTTSUUSUURTTRTTSUUUWWUWWXZZXZZWYYWYYUWWVXXXZZXZZY[[[[[\\\[]][]]\^^\^^[]][]]\^^[]]]__]__\^^]__^``\^^]__]__\^^Z\\Y[[Y[[Z\\UWWSUURTTOQQMOOKMMHJJDFFCEE?AA>@@:<<688577355133.00.00,..+--*,,)++)++)++*,,+--,..-//.000223555779;;9;;8::<>>?AA@BBBDDCEEDFFFHHFHHIKKIKKIJLIJLIKKIKKIKKHJJJLLIKKIKKGIIGIIHJJHJJGIIGIIFHHFHHGIIGIIFHHFHHFHHEGGEGGHHHFFFDFFDFFEGGEGGDFFDFFFHHEGGDFFDFFHHHFFFFFFEEEEEEFFFFFFFFFEEEFFFFFFFFFGGGFFFGGGIIIJJJKKKKKKKKKJJJKKKJJJKKKLLLLLLKKKJJJJJJKKKKKKJJJJJJIIIJJJJJJKKKKKKLLLKKKKKKKKKKKKKKKKKKKKKMMMMMMMMMNNNNNNOOOPPPNNNPPPPPPOOOOOONNNOOOOOOOOONNNMMMLLLKKKLLL111<<?A#&(!"$) %!#!#(*(**+%&()*+)-$48$@S#?R)8"1#"'&% $$""!GIIGIIFHHFHHGIIGIIGIIGIIHJJIKKIKKHJJIKKIKKJLLJLLIKKIKKIKKJLLIKKKMMJLLJLLKMMLNNKMMLNNKMMJLLKMMKMMLNNLNNLNNLNNMOOLNNKMMLNNMOOLNNMOONPPNPPMOONPPLNNMOOMOOMOOLNNMOOMOOLNNMOOOQQOQQOQQQQQRRRQSSQSSRTTSUURTTRTTSUUSUUTVVUWWTVVVXXUWWWYYWYYVXXXZZWYYWYYXZZZ\\[]]\^^\^^\^^]__]__^```bb`bb_aaaccceeacc`bbacc`bb_aaacc`bb^``_aa_aa^``]__[]]Y[[VXXTVVQSSMOOLNNIKKEGGBDD>@@<>>:<<688355244022133-//.00-///02./1/11133355577577799:<<:<<>@@ACC@BBBDDEGGFHHEGGHJJGIIHJJHJJHJJGIIHJJKKKIIIFHHFHHFHHEGGEGGDFFEGGCEECEEEGGGGGFFFFFFGGGFFFFFFFFFFFFEEEFFFEEEFFFEEEEEEEEEHHHKKKKKKJJJJJJIIIJJJIIIIIIIIIIIIIIIIIIJJJJJJIIIHHHIIIHHHIIIIIIIIIIIIIIIJJJJJJKKKJJJKKKKKKLLLKKKMMMLLLMMMMMMNNNOOOMMMMMMNNNOOONNNNNNOOOOOOMMMLLLKKKMMMKKKGGG---:::DDD@@@===8::688,..-//+--+--,...00/11/111331331333553552444664663554664664666887996887996888::9;;:;==>@!$&"%("'!&$&"+-*,')+,*+)*'((,#37$@S0C / .$$"!!!""HJJHJJGIIGIIHJJHJJHJJHJJIKKIKKIKKIKKIKKIKKIKKJLLJLLKMMKMMJLLJLLLNNKMMKMMKMMKMMMOOLNNLNNMOOLNNLNNLNNMOOLNNLNNLNNMOOJLLLNNLNNKMMMOOMOOLNNMOOLNNKMMLNNKMMLNNKMMKMMKMMKMMKMMKMMKMMLNNKMMKMMKMMKMMKMMKMMKMMLNNMOOJLLKMMLNNKMMLNNLNNMOOMOOMOOLNNLNNLNNKMMMOOMOONPPMOOOQQNPPNPPNPPOPRPQSPQSQRTQSSTVVUWWUWWUWWUWWVXXVXXY[[WYYY[[\^^]__]__]__]___aa_aa_aabddceedffdffeggdffeggdffdffdffbddacc_aa^``[]]Z\\XZZWYYTVVPRRLNNJLLFHH?AA<>>:<<8::799355133022-//,..,..,..-///110221332443555776889;;<>>>@@?AACEECEEDFFFHHFHHGIIGIIHJJEGGGIIIIIHHHHHHGGGGGGGGGFFFFFFFFFHHHKKKKKKKKKKKKJJJKKKKKKKKKJJJIIIIIIJJJIIIIIIHHHHHHHHHIIIIIIHHHIIIIIIIIIIIIIIIJJJJJJJJJLLLJJJJJJKKKLLLMMMLLLMMMMMMLLLNNNMMMNNNMMMNNNMMMOOONNNLLLLLLKKKJJJDDD,,,888CCC???<<<:::555+--,..*,,*,,+--.00/110221331331331334663554663554664665775776885776886887997998::9:<<=?##"#$%""$$$$##!!##**--+,)*,-,=>4>)3!%' #")( '$%!%!)%IKKGIIHJJGIIHJJHJJHJJHJJJLLJLLGIIIKKIKKJLLIKKKMMLNNLNNKMMKMMJLLLNNKMMLNNLNNKMMLNNMOOMOOMOOLNNLNNMOOMOOMOONPPMOOMOOMOONPPMOOMOOMOONPPLNNMOOMOOLNNLNNLNNLNNLNNLNNKMMLNNLNNKMMJLLKMMLNNKMMKMMKMMLNNKMMJLLKMMKMMJLLJLLJLLKMMKMMJLLKMMKMMJLLJLLLNNJLLJLLJLLJLLLNNKMMJLLKMMJLLJLLKLNJKMJKMKLNKMMJLLJLLJLLJLLJLLJLLHJJJLLKMMIKKHJJJLLJLLJLLIKKJLLKMMLNNKMMKMMLNNKMMLNNLNNMOOMOONPPOQQOQQQSSSUUQSSSUUSUUSUUUWWVXXXZZZ\\Y[[[]]_aaaccbddaccacc`bbceeceeceebddacc`bb]__Y[[WYYUWWSUURTTMOOHJJDFFACC;==577244133.00,..*,,(**)++)++)++*,,000222444666999>>>???AAACCCEEEIIILLLNNNNNNNNNOOOOOONNNMMMLLLMMMMMMKKKKKKJJJIIIIIIJJJHHHHHHIIIJJJJJJJJJIIIJJJIIIJJJKKKJJJJJJKKKJJJJJJJJJJJJMMMLLLMMMLLLMMMLLLMMMLLLLLLMMMLLLLLLJJJJJJFFF---===BBB@@@<<<888444-//-//*,,*,,+--.00/110221331332441333553554664664664665774666885776886887998::9;;89;<=?!!""  ''"00)*)* 12&78 $.) " ")(!('# $!&0,",(%!GIIFHHGIIGIIFHHHJJHJJIKKIKKIKKHJJIKKKMMJLLIKKIKKLNNLNNJLLJLLJLLJLLJLLKMMKMMLNNLNNMOOKMMLNNLNNKMMNPPNPPLNNMOOMOOMOOMOOOQQOQQNPPNPPNPPLNNNPPMOOMOOMOONPPMOOLMOLMOLMOLMOMNPMNPLMOMNPLMONOQMOOLNNNPPLNNMOOLNNLNNLNNLNNLNNLNNKMMLNNLNNMOOLNNJLLLNNJLLKMMJLLKMMKMMJLLJKMKLNIJLJKMMNPJKMIJLLMOKLNIJLIJLJKMIJLIJLJLLIKKJLLKMMJLLIKKJLLIKKJLLIKKJLLIKKIKKIKKIKKIKKIKKHJJIKKIKKHJJIKKIJLJKMIJLHIKHIKHIKHIKIJLJKMHIKGIIHJJIKKGIIGIIGIIIKKHJJJLLIKKJLLJLLMNPOPRNPPQSSRTTXZZXZZZ\\Z\\\^^_aa`bbceedffefhfgihjjikkhjjhjjhjjfhhcee_aa\^^XZZSUUOQQLLLGGGBBB;;;888555000+++)))(((&&&%%%&&&(((+++---000666888;;;???AAAEEEGGGHHHIIIKKKMMMMMMLLLMMMLLLMMMLLLLLLKKKKKKJJJJJJMMMKKKKKKLLLLLLMMMKKKKKKLLLLLLLLLLLLLLLMMMLLLKKKJJJIIIGGGDDD---;;;BBB===<<<688355-//+--+--*,,,...00.00/110221332442442444664664664664664664665775775775776887998::8::;==## ! $#,=<-,+)*(-+(&'%" ")&($%")%!+')%!FHHGIIGIIGIIFHHGIIGIIHJJGIIHJJGIIGIIHJJIKKJLLIKKJLLJLLIKKKMMIKKJLLJLLKMMKMMKMMLNNMOOJLLKMMKMMKMMKMMLNNKMMLNNMOOMOOLNNMOOMOOLNNMOOLNNLNNMOOMOOLNNKMMKMMMOOLMONOQLMOKLNNOQMNPLMOKLNLMOKLNLNNKMMKMMLNNLNNMOOLNNMOOLNNLNNKMMKMMLNNLNNKMMKMMJLLKMMKMMKMMKMMKMMJLLKMMLMOJKMIJLKLNKLNJKMJKMLMOLMOJKMKLNKLNJKMJKMJLLKMMKMMKMMKMMIKKHJJKMMJLLIKKJLLJLLIKKIKKKMMIKKIKKGIIIKKIKKHJJIKKIJLJKMIJLIJLIJLIJLHIKHIKHIKIJLGIIGIIGIIGIIHJJGIIFHHFHHGIIEGGEGGFHHFGIGHJEGGFHHFHHEGGEGGDFFEGGEGGDFFDFFDFFDFFEFHGHJGIIHJJKMMKMMMOONPPPRRRTTWYYWYYY[[\^^```dddeeefffgggffffffggggggeeecccbbb___ZZZUUUOOOKKKEEE@@@<<<888222---+++'''$$$$$$$$$$$$%%%)))---000222777;;;>>>BBBCCCGGGKKKMMMMMMOOOPPPPPPPPPOOOOOONNNNNNNNNLLLMMMLLLKKKJJJHHHCCC///<<>"" &'",,! ,65#43'&)')')'(&)'#!$#%,)!(%%!%!$!#  FHHEGGFHHGIIFHHGIIFHHFHHFHHHJJGIIGIIGIIHJJIKKIKKHJJIKKHJJIKKIKKJLLIKKJLLJLLKMMJLLKMMKMMJLLKMMJLLKMMKMMKMMLMOKLNKMMMOOLNNLNNKMMKMMJLLKMMKMMMOOLMOKLNKLNKLNKLNLMOKLNKLNLMOKLNJKMJKMJKMJKMKLNKLNKMMKMMKLNLMOKMMLNNKMMLNNJLLKMMKMMKMMKMMKMMKLNKLNKLNJKMKLNKLNKLNJKMKLNJKMJKMKLNKLNJKMJKMKLNKLNKLNKLNKLNJKMJKMJKMKLNJLLIKKJLLIKKHJJKMMIKKHJJJLLJLLJLLIKKJLLJLLKLNIJLJKMJKMIJLJKMKLNJKMIJLIJLIJLIJLHIKIJLJKMIJLHIKGHJHJJHJJIKKHJJGIIFHHGIIGIIFGIGHJFGIFGIFGIFGIGIIFHHDFFEGGEGGEGGEGGDFFEFHDEGDFFDFFCEECEECEEDFFCEECEECEECEEDFFBDDACCBDDDDDCCCCCCCCCEEEEEEHHHIIIKKKLLLMMMPPPRRRPPPRTTSUURTTTVVSUUTVVSUUTVVWWWVVVSSSRRRSSSRRRQQQOOOLLLKKKEEEBBB<<<888666555333000......,,,.../////////111444999===>>>BBBFFFHHHGGGGGGGGGAAA333@@@@@@???===799466.00,..,..+--,../11/11.000222441332442443553553554664664664664664666886885775776888::<>>##%%"00,,))(()''%$"&$ %$!(%")&")&%""# " !GIIEGGEGGGIIGIIFHHEGGGIIGIIHJJHJJHJJIKKHJJHJJHJJIKKHJJIKKHJJJLLKMMKMMIKKIKKJLLJLLJLLJLLJLLJLLKMMJLLKMMKMMJKMJKMKMMKMMLNNKMMKMMLNNKMMKMMKMMKMMKLNJKMIJLIJLJKMIJLIJLJKMIJLJKMJKMIJLJKMJKMLMOKLNJLLJLLJKMJKMJLLJLLKMMJLLKMMKMMJLLJLLIKKIKKIJLIJLKLNJKMJKMJKMJKMIJLHIKIJLIJLJKMJKMKLNIJLIJLJKMJKMJKMIJLJKMKLNJKMIJLHJJIKKIKKIKKIKKHJJGIIGIIHJJJLLHJJJLLJLLIKKJKMJKMIJLIJLIJLJKMIJLIJLIJLHIKHIKHIKHIKHIKIJLIJLGHJHIKIKKIKKIKKGIIGIIGIIGIIGIIHIKFGIGHJFGIEFHFGIGIIFHHFHHHJJFHHFHHEGGFHHFGIFGIDFFDFFDFFCEEDFFEGGEGGDFFEGGBDDCEEBDDBDDCEEDDDDDDCCCDDDCCCDDDCCCDDDEEEFFFFFFFFFEEEEEECEEBDDBDDCEEDFFBDDDFFDFFFFFFFFFFFGGGHHHJJJIIIHHHJJJLLLLLLNNNMMMQQQPPPRRRSSSRRRTTTWWWVVVWWWXXXXXXWWWVVVTTTRRRRRRQQQOOOHHHDDD@@@888333(((---222,,,***+++(**')))++"$$-//+---//.00/11/11022244133244244355355466355466466355466577688577577688577688;=="&& "" #--%33%%&&)),*(&%##!&%('")&"$! EGGFHHEGGFHHHJJFHHGIIFHHEGGFHHHJJGIIGIIHJJHJJGIIGIIHJJJLLIKKHJJJLLHJJHJJIKKJLLIKKJLLJLLJLLKMMJLLLNNJLLKMMJLLJLLKLNJKMLNNKMMKLNKLNLMOJKMKLNKLNKLNJKMIJLJKMIJLJKMIJLJKMJKMJKMLKMKJLHIKIJLKLNJKMJKMKLNJKMJKMKMMIKKJLLJLLJLLJLLJLLJLLIKKIKKIJLHIKIJLJKMIJLIJLJKMIJLHIKHIKIJLIJLIJLJKMJKMIJLIJLHIKIJLIJLHIKIJLIJLHIKIJLHIKHJJHJJIKKHJJIKKHJJHJJIKKHJJHJJIKKGIIGHJHIKIJLHIKIJLGHJHIKHIKIJLHIKHIKHIKHIKGHJGHJGHJGHJGHJHIKHIKGHJFGIFGIFGIFHHFHHEFHFGIEFHFGIDEGGHJFGIFGIEFHDEGFHHEGGDEGDEGEFHEFHEFHEFHDEGDEGDEGEFHEGGDFFDFFDFFCEECEECEECEEBDDACCDDDEEEDDDDDDDDDDDDCEEEGGFHHEGGDFFCEECEEDFFDFFDFFDFFDFFCEEDFFDFFDFFCEEBDDCEEDFFEEEFFFGGGGGGGGGHHHHHHHHHIIIHHHJJJIIIJJJIIIIIIJJJJJJLLLJJJKKKMMMNNNMMMNNNOOOQQQPPPPPPMMMPPPIII777>>>GGGAAA:::688,.."$$-//+---///11/11/11/111332441331333553552444664664663553554665776885774664665779;;%)) ! "+46!##%$&+-./,-!  &"%!%"    +    EGGFHHDFFDFFFHHGIIFHHFHHGIIHJJGIIHJJGIIIKKHJJGIIGIIHJJIKKIKKHJJIKKIKKIKKIKKIKKJLLIKKJLLJLLJLLKMMKMMJLLKMMKMMKMMKLNKLNKMMKMMJKMJKMKLNLMOKLNJKMJKMJKMJKMJKMIJLIJLJKMJKMJKMJKMLKMJIKIJLJKMIJLIJLJKMJKMHIKIJLIKKJLLIKKIKKIKKJLLJLLJLLJLLJLLIJLIJLJKMIJLHIKIJLIJLJKMHIKJKMIJLHIKIJLJKMHIKJKMHIKHIKHIKIJLHIKHIKHIKHIKHIKHIKHJJHJJHJJIKKIKKHJJGIIHJJHJJHJJGIIHJJHIKHIKGHJGHJGHJGHJGHJHIKHIKHIKGHJHIKHIKGHJFGIGHJFGIFGIGHJFGIEFHDEGEFHEFHDFFEGGEFHDEGEFHDEGDEGEFHEFHDEGDEGDEGCEEBDDCDFCDFCDFDEGCDFDEGCDFDEGCDFBCECEEBDDBDDCEEACC@BBBDDBDDACCACCCCCDDDCCCBBBCCCCCC@BBACCDFFDFFBDDCEECEECEECEECEEDFFDFFEGGCEEBDDCEEDFFCEEDFFDFFFFFFFFFFFGGGEEEHHHHHHHHHHHHIIIIIIHHHJJJHHHIIIJJJJJJIIIIIIJJJKKKLLLKKKIIIJJJJJJJJJHHHIIIIII<<<222666AAA>>>:::688355022-//,..-//.00/11022133022133244244244355466466355355466466355466466355355466466799'++  !(*#%!#%,.(57)*%&#"#"%$$#)%($ +  +   + +  EGGEGGFHHDFFEGGEGGFHHDFFFHHFHHFHHGIIHJJFHHIKKGIIHJJGIIIKKHJJHJJIKKIKKJLLHJJJLLIKKIKKJLLJLLJLLJLLKMMJLLJLLIJLKLNKLNJKMLMOKLNKLNJKMKLNLMOKLNKLNJKMIJLIJLJKMJKMJKMKLNJKMIJLIJLJKMJKMIJLIJLJKMKLNJKMJKMHIKIJLIJLIJLIJLHIKIJLIJLIKKHJJIJLIJLIJLHIKJKMJKMIJLJKMIJLIJLHIKHIKIJLHIKHIKHIKHIKGHJIJLHIKHIKHIKHIKHIKHIKHIKHIKHIKHIKGHJHJJFHHIKKGIIHIKHIKHIKHIKHIKGHJHIKGHJFGIGHJGHJHIKGHJGHJFGIFGIGHJGHJHIKGHJFGIGHJFGIFGIFGIDEGFGIDEGEFHEFHEFHEFHFGIDEGEFHEFHDEGEFHFGIEFHDEGEFHDEGDEGBCEBCEBCEBCECDFCDFBCEBCEABDBCEABDBCEABD@AC@AC@AC@AC@ACACC@BB?AA?AA?AA?AA>?A?@B?@B?@B>?A@AC@ACABDABDABDABDBCEBCE@ACABDBCEABDABDCDFBCECEECEEFFFEEEFFFFFFFFFGGGFFFEEEGGGGGGHHHFFFHHHHHHIIIIIIIIIHHHIIIJJJJJJLLLJJJIIIKKKLLLIIIIIIHHHHHH===444:::???<<<999888444///!!! "",..+--,..-///11/11022022022133133244355244244244466355355244355466355355355466688'++%*!#(%**=F!4=',',')') ,,!--#"      CEEEGGFHHFHHFHHFHHEGGFHHGIIGIIHJJFHHFHHFHHHJJHJJHJJGIIHJJGIIIKKGIIJLLJLLIKKIKKIKKHJJJLLLNNKMMIKKJLLJLLKMMIJLKLNJKMJKMJKMJKMKLNKLNLMOKLNKLNLMOJKMIJLIJLKLNJKMJKMJKMJKMJKMKLNJKMJKMJKMIJLJKMIJLIJLJKMIJLJKMKLNIJLIJLHIKIJLJKMHJJJLLIJLJKMIJLIJLIJLJKMIJLHIKJKMJKMHIKHIKJKMHIKHIKIJLHIKHIKHIKHIKIJLHIKIJLIJLHIKHIKHIKHIKIJLIJLHJJGIIHJJGIIGHJGHJHIKHIKGHJGHJHIKFGIFGIFGIGHJGHJHIKGHJGHJFGIGHJGHJGHJHIKHIKFGIEFHFGIFGIFGIGHJEFHEFHEFHDEGDEGDEGEFHDEGDEGEFHDEGDEGDEGDEGDEGDEGCDFDEGCDFCDFABDDEGBCEABDBCEABDBCE@ACABD@AC@AC@ACABD@AC@AC?AA>@@>@@?AA?AA>@@>?A>?A=>@>?A=>@>?A@AC?@B?@B@AC@AC@AC@AC@AC@AC@AC@AC@ACABD@ACBDDBDDCCCCCCEEEEEEDDDEEEEEEDDDEEEEEEFFFFFFFFFHHHGGGGGGIIIGGGGGGIIIHHHIIIJJJIIIJJJJJJHHHHHHGGGEEEAAA>>>??????===999777333///***)++*,,+--,...00/11/11/11022133244466244355355244244244355244466244355244466244355466488 %#( *//BK09,1%*#%)+))## + + + + + +      DFFEGGDFFEHEFIFEHEFIFGIIGIIGIIGIIHJJGIIFHHGIIHJJJLLHJJHJJHJJJLLIKKIKKIKKIKKIKKHJJIKKIKKJLLIKKJLLIKKJKMIJLJKMLMOKLNKLNJKMKLNLMOJKMKLNJKMLMOJKMJKMJKMIJLIJLJKMJKMJKMIJLIJLJKMIJLIJLJKMJKMIJLHIKJKMJKMIJLIJLJKMHIKIJLJKMJKMIJLIJLIJLHIKIJLHIKJKMHIKGHJIJLIJLIJLIJLIJLIJLIJLHIKJKMJKMIJLHIKHIKHIKIJLHIKHIKHIKHIKHIKGHJGHJHIKGHJHIKIJLHIKGHJHIKHIKHIKGHJGHJGHJGHJHIKHIKFGIGHJHIKHIKGHJFGIGHJFGIFGIFGIGHJFGIFGIEFHFGIEFHFGIFGIFGIEFHDEGEFHDEGDEGDEGDEGDEGCDFDEGDEGDEGDEGCDFCDFBCECDFCDFCDFCDFCDFCDFABDBCEBCEBCEABDABDABD@ACABDABDABD@ACABD@AC>?A?@B@AC=>@>?A>?A=>@>?A=>@>?A>?A?@B@AC@AC@AC@AC?@B@AC?@B@AC@AC@AC@AC@ACABDBCECCCCCCCCCDDDDCEDCECBDDCEEEEGGGDCEEDFFEGFEGFEGFEGFEGEDFGFHIHJHHHHHHIIIIIIIIIHHHGGGFFFEEEDDDBBB???>>>===:::999666222-//(**(***,,,..-///11.00.00133133244133355355355244355244133133133355355355355355355355799'++  !$(.*8&4%1#/$0$0$   +   +  EGGFHHFHHFIFEHEEHEFIFFHHEGGGIIFHHIKKGIIGIIGIIFHHFHHGIIHJJIKKIKKIKKIKKIKKHJJIKKJLLJLLIKKIKKIKKJLLIKKJKMJKMJKMKLNKLNJKMKLNKLNLMOKLNKLNKLNLMOKLNKLNIJLIJLIJLHIKIJLJKMJKMIJLIJLIJLIJLJKMIJLIJLHIKJKMJKMHIKHIKIJLIJLKLNJKMIJLHIKHIKIJLIJLGHJHIKJKMIJLIJLIJLJKMHIKIJLIJLIJLIJLIJLHIKGHJHIKHIKHIKHIKHIKHIKHIKHIKHIKHIKIJLHIKHIKHIKGHJHIKGHJIJLIJLIJLHIKGHJGHJGHJGHJHIKHIKHIKGHJGHJFGIFGIFGIFGIFGIFGIFGIFGIEFHEFHEFHGHJFGIFGIEFHFGIDEGEFHEFHEFHDEGDEGCDFEFHEFHCDFDEGFGIEFHCDFCDFBCEBCECDFBCEBCECDFBCEBCEABD@ACABD@ACABDBCE@ACABD@ACABD?@B>?A?@B@AC?@B>?A>?A>?A>?A=>@>?A>?A<=?<=?>?A>?A>?A>?A?@B@AC@AC@AC?@B@AC?@B@ACABD@ACABDDDDBBBBBBCCCDCEEDFEDFEDFDDDEEEFEGFEGEDFEDFFEGFEGFEGFEGFEGGFHGGGHHHHHHHHHHHHHHHFFFGGGEEEEEECCC@@@>>>===<<<888555222.00(***,,,..-//-//.00/11022244022244133133133355355355355244244355244244244244244577577&((    %(.!/ ('** % +  + +  EHEEHEEHEFIFHKHFIFFIFFHHGIIFHHGIIGIIHJJGIIGIIGIIGIIFHHHJJIKKIKKHJJJLLIKKIKKIKKJLLJKMJKMIJLIJLJKMJKMJKMKLNKLNKLNKLNJKMKLNKLNKLNKLNLMOKLNJKMLMOJKMJKMKLNIJLIJLJKMKLNJKMIJLIJLIJLJKMIJLIJLIJLHIKIJLIJLJKMIJLIJLIJLJKMKLNJKMIJLIJLIJLIJLIJLHIKJKMJKMIJLHIKIJLHIKIJLJKMJKMIJLIJLHIKHIKIJLIJLIJLHIKHIKJKMHIKHIKHIKHIKIJLHIKIJLHIKJKMIJLGHJHIKHIKHIKIJLHIKHIKHIKGHJGHJFGIHIKHIKHIKFGIHIKGHJFGIFGIFGIFGIGHJFGIEFHGHJGHJFGIFGIGHJFGIDEGFGIEFHFGIDEGEFHDEGEFHEFHEFHDEGDEGDEGDEGDEGDEGCDFCDFBCEBCEDEGBCEABDABD@ACABDABDABDABDABD@AC?@B@AC@AC@AC=>@=>@>?A>?A?@B>?A?@B>?A=>@=>@=>@<=??@B>?A?@B>?A=>@>?A?@B@AC@AC?@B@AC@AC@ACABDABDABD@ACBACDCEBCEBCEDCEDCEDCEDCEEDFEDFDCEFEGFEGFEGFEGFEGFEGGFHHHHHHHIIIGGGGGGGGGFFFEEEGGGDDDBBB???>>>===:::777666333-//)++*,,-//.00/11/11/11022022022244244244133355244133133244244355133244244133466466     !%%!#%)  +  EHEEHEFIFEHEDGDFIFFIFGIIFHHFHHFHHGIIIKKHJJHJJHJJIKKHJJHJJHJJIKKJLLIKKHJJGIIIKKIKKJKMJKMJKMHIKKLNKLNJKMJKMKLNKLNJKMJKMIJLKLNJKMJKMLMOKLNIJLJKMJKMKLNJKMIJLIJLIJLJKMJKMIJLIJLJKMJKMJKMIJLJKMJKMJKMIJLJKMJKMJKMIJLIJLIJLIJLJKMIJLKLNJKMIJLJKMJKMIJLIJLIJLIJLIJLIJLIJLIJLIJLHIKIJLIJLIJLIJLIJLIJLIJLIJLJKMHIKIJLIJLIJLIJLJKMIJLIJLHIKIJLIJLHIKHIKHIKGHJHIKHIKHIKGHJFGIGHJHIKFGIFGIHIKGHJFGIFGIGHJGHJGHJFGIFGIFGIFGIFGIDEGFGIFGIEFHEFHFGIDEGDEGEFHDEGDEGDEGDEGEFHCDFBCEDEGDEGCDFCDFBCEBCEBCEBCEBCEBCEABDBCEABDABDABD@ACABDABD@AC?@B@AC?@B>?A?@B>?A=>@=>@>?A>?A<=?=>@=>@=>@=>@<=?@AC?@B?@B=>@>?A>?A?@B?@B?@B>?A@AC?@B?@BABDABDABDDCEEDFBCE@ACBACCBDCBDBACDCEEDFEDFEDFFEGEDFFEGFEGFEGGFHGGGEEEAAACCCGGGGGGFFFEEEDDDDDDAAA???<<<<<<:::888444333,..)++*,,,...00/11/11022022133022244133133244355244022133355244133133244244466/11       +   ",   EGGEHEDGDFHHDFFEGGFHHFHHEGGFHHFHHGIIHJJIKKHJJGIIIKKHJJGIIHJJHJJGIIIKKHJJGIIHJJJLLIKKJLLIKKIKKKMMKMMKMMJLLIJLJKMLMOJKMIJLJKMJKMJKMJKMKLNJKMIJLIJLJKMKLNHIKIJLJKMKLNJKMIJLJKMJKMIJLJKMIJLIJLJKMIJLIJLHIKJKMJKMKLNIJLJKMJKMJKMIJLKLNJKMJKMJKMKLNJKMIJLIJLKLNIJLIJLIJLIJLGHJHIKIJLJKMHIKIJLIJLIJLIJLHIKIJLIJLIJLHIKHIKHIKHIKIJLHIKHIKHIKGHJHIKHIKGHJGHJHIKHIKHIKGHJFGIGHJHIKGHJFGIGHJGHJGHJGHJHIKGHJFGIFGIFGIGHJEFHFGIEFHEFHEFHDEGDEGDEGDEGEFHDEGDEGDEGCDFDEGDEGCDFCDFCDFCDFBCECDFBCECDFBCEBCEBCEABDCDFBCEABD@AC@ACABDABD@AC?@B?@B@ACABD?@B?@B?@B>?A=>@>?A=>@;<>=>@<=?=>@<=?<=?=>@=>@>?A=>@>?A>?A>?A>?A>?A>?A?@B>?A>?A@ACABDABDCBDDCEABDABDCBDCBDCBDBACBACDCEDCEEDFDCEFEGEDFEDFEEEDDDBBBAAABBBDDDFFFGGGFFFEEECCCDDDAAA???<<<;;;999888555333,..)+++---//.00/11/11022022133133022133133244244133244244133133133244244568./1         + ) +   + EGGDGDCFCDFFFHHFHHFHHGIIFHHFHHFHHFHHFHHGIIGIIGIIHJJHJJGIIIKKHJJGIIIKKHJJGIIJLLJLLIKKIKKIKKLNNKMMIKKIKKJLLKLNJKMJKMJKMJKMJKMIJLIJLIJLJKMJKMJKMJKMJKMJKMJKMIJLJKMIJLIJLJKMIJLIJLJKMIJLJKMJKMJKMJKMIJLIJLHIKIJLJKMIJLIJLJKMJKMJKMKLNIJLIJLJKMJKMJKMHIKJKMIJLIJLIJLIJLHIKGHJIJLHIKHIKIJLHIKIJLIJLIJLIJLHIKIJLGHJHIKHIKHIKHIKHIKGHJIJLIJLHIKIJLGHJHIKJKMHIKGHJGHJHIKIJLGHJGHJGHJFGIGHJGHJFGIFGIGHJGHJFGIFGIFGIFGIEFHEFHFGIFGIEFHEFHDEGDEGEFHEFHDEGDEGDEGCDFCDFCDFCDFCDFCDFCDFBCEBCEBCEBCEBCECDFBCEABDABDABD@ACABD@ACABD@AC?@B?@B?@B@AC?@B?@B?@B?@B>?A=>@=>@<=?<=?=>@<=?;<>;<><=?<=?=>@<=?=>@>?A>?A=>@?@B>?A?@B?@B>?A>?A?@B?@B?@BA@BBACABDABDDCEDCECBDCBDCBDBACBACBACBACCBDBACCBDCCCCCCBBBBBBDDDDDDFFFFFFEEEDDDCCCBBBAAA>>>===;;;999777555333,..*,,,..-///11.00.00/11022133133133133244244244244244133022133133133688%&(           +  # +  +  +DFFEGGEGGDFFFHHFHHFHHFHHGIIFHHGIIEGGFHHGIIGIIGIIGIIHJJHJJHJJGIIGIIHJJHJJHJJHJJKMMJLLIKKIKKKMMKMMJLLIKKIKKJKMJKMIJLJKMJKMJKMJKMIJLHIKIJLKLNLMOKLNJKMIJLHIKIJLJKMIJLJKMJKMJKMJKMJKMIJLIJLIJLKLNJKMJKMIJLHIKIJLJKMJKMIJLJKMHIKIJLKLNJKMJKMJKMJKMIJLIJLIJLIJLHIKIJLIJLIJLIJLIJLIJLHIKHIKHIKHIKHIKIJLJKMHIKHIKGHJHIKGHJHIKIJLHIKHIKHIKHIKGHJGHJGHJIJLIJLGHJHIKHIKHIKGHJIJLHIKHIKHIKGHJGHJFGIGHJHIKGHJGHJGHJEFHFGIFGIFGIFGIFGIGHJEFHEFHEFHDEGEFHFGIDEGDEGDEGEFHCDFBCECDFBCECDFCDFBCECDFDEGCDFBCEABDABDABDBCEABD@AC?@B@AC@AC@AC@AC?@B>?A>?A?@B>?A>?A>?A=>@<=?<=?;<>=>@<=?;<>;<>;<><=?=>@>?A=>@=>@=>@=>@?@B>?A=>@>?A>?A@AC>?A?@B@ACBACBAC@ACABDBACBACBACCBDDCECBDDCECBDCBDCBDDCEBACEDFEDFEEEFFFEEEEEEFFFEEEDDDCCCCCCBBB???>>>===;;;888666244133-//+--,..-///11.00/11/11/11022244133022244133244133022133133/02235457#$&           + + EGGEGGEGGEGGFHHGIIGIIFHHGIIFHHGIIEGGFHHHJJGIIHJJIKKGIIHJJHJJHJJHJJHJJIKKIKKHJJJLLJLLIKKIKKIKKHJJIKKJLLIKKJKMJKMIJLIJLHIKJKMJKMJKMJKMHIKIJLKLNKLNKLNIJLIJLIJLIJLJKMIJLJKMJKMJKMJKMJKMJKMJKMJKMIJLJKMJKMHIKIJLIJLJKMIJLJKMHIKIJLJKMJKMIJLIJLIJLIJLJKMIJLIJLIJLGHJHIKHIKIJLIJLIJLIJLIJLHIKIJLIJLHIKHIKHIKHIKIJLIJLIJLIJLIJLIJLHIKHIKJKMIJLIJLHIKHIKHIKGHJGHJHIKGHJGHJHIKGHJGHJHIKHIKHIKGHJGHJFGIGHJGHJFGIFGIEFHFGIFGIGHJEFHFGIEFHEFHEFHDEGEFHEFHEFHDEGDEGDEGBCEBCEDEGCDFABDCDFCDFABDCDFBCE@AC@ACABDABD@ACABDBCE?@B@AC@AC?@B?@B?@B?@B?@B>?A>?A>?A>?A>?A=>@<=?<=?;<><=?<=?;<><=?<=?;<>;<><=?<=?<=?<=?=>@=>@>?A>?A?@B=>@>?A?@B?@BA@BA@B@AC?@BCBDBACBACCBDCBDCBDDCECBDDCEDCEDCEDCEDCEFEGEEEDDDEEEEEEFFFEEEDDDCCCCCCBBB???===;;;;;;888666244022-//)++,...00.00022022022/11133133133133133022133133022022133124235"#%        +      DGDDFFEGGEGGFHHFHHHJJEGGGIIFHHGIIFHHHJJHJJGIIIKKIKKFHHFHHFHHHJJGIIIKKIKKGIIHJJIKKIKKHJJJLLIKKIKKJLLIJLIJLHIKIJLJKMIJLKLNIJLIJLJKMIJLHIKIJLJKMJKMIJLIJLIJLIJLJKMJKMIJLIJLJKMHIKIJLJKMJKMIJLIJLIJLIJLJKMKLNHIKHIKHIKJKMJKMJKMJKMIJLIJLIJLHIKIJLJKMJKMKLNKLNHIKHIKIJLIJLIJLIJLHIKIJLHIKHIKIJLJKMJKMIJLHIKGHJHIKIJLIJLHIKHIKHIKHIKIJLHIKHIKGHJGHJGHJHIKHIKGHJGHJFGIHIKGHJHIKGHJHIKFGIFGIGHJGHJFGIFGIFGIEFHFGIGHJFGIEFHEFHEFHEFHEFHDEGCDFDEGDEGEFHDEGEFHEFHDEGCDFCDFCDFCDFCDFABDBCEBCEBCE@ACABDABD@ACABDABDABD?@B?@B?@B@AC@AC?@B?@B>?A=>@?@B>?A=>@=>@<=?=>@<=?;<>;<>;<>:;=;<>;<>;<>=>@<=?;<><=?<=?=>@=>@=>@<=?=>@=>@=>@>?A@AC>?A>?A?@B?@B?@B@?A@?AA@BCBDCBDBACBACBACDCEDCEDCEDCECCCCCCDDDCCCDDDEEEDDDDDDDDDCCCBBBAAA???===;;;:::688466244022-//*,,.00/11.00/11022/11022022133133133022022022133022013124.13        +  + + +   +    FIFEGGDFFEGGFHHFHHEGGFHHGIIGIIGIIEGGFHHHJJHJJGIIGIIFHHGIIGIIHJJGIIGIIGIIIKKHJJGIIIKKIKKJLLIKKJLLHJJHIKJKMIJLJKMJKMIJLJKMJKMIJLIJLJKMIJLJKMIJLIJLJKMJKMHIKIJLJKMIJLIJLIJLIJLGHJIJLJKMJKMIJLHIKIJLJKMIJLIJLHIKIJLHIKKLNJKMIJLIJLIJLIJLJKMIJLIJLGHJHIKIJLIJLHIKHIKIJLHIKIJLIJLHIKHIKHIKIJLHIKIJLIJLHIKHIKGHJHIKHIKIJLHIKGHJIJLIJLIJLIJLHIKHIKIJLHIKIJLHIKGHJHIKGHJGHJIJLHIKHIKGHJGHJGHJHIKGHJFGIFGIEFHFGIEFHFGIFGIEFHDEGDEGFGIEFHEFHEFHEFHDEGDEGDEGDEGDEGEFHCDFDEGCDFBCEBCEBCEBCECDFBCE@ACABD@AC@AC@AC@AC?@B>?A?@B>?A?@B?@B>?A?@B>?A=>@=>@=>@=>@=>@=>@;<>;<>:;=;<>:;=:;=;<>;<>:;=;<>;<><=?;<><=?<=?<=?<=?<=?=>@;<>>?A>?A>?A>?A=>@>?A>?A>?A@?AA@BBACBACA@BBACA@BBACBACBACDCECBDDDDDDDDDDCCCCCCDDDCCCCCCBBBAAA@@@???>>>===999999688355133022-//,..-///11/11.00.00133022022022022022022022022133022124./1      +   + + + + + +   FHHFHHEGGFHHEGGFHHFHHEGGFHHFHHEGGFHHFHHFHHFHHGIIGIIGIIFHHHJJHJJGIIHJJGIIKMMJLLGIIIKKHJJHJJHJJHIKIJLIJLIJLJKMJKMJKMIJLIJLJKMJKMJKMJKMJKMIJLIJLIJLIJLHIKIJLIJLIJLJKMIJLIJLIJLIJLJKMIJLJKMIJLIJLIJLJKMJKMJKMIJLJKMJKMIJLHIKIJLIJLIJLIJLIJLIJLJKMHIKIJLIJLHIKJKMHIKHIKIJLIJLHIKIJLIJLHIKIJLIJLIJLHIKGHJGHJHIKHIKIJLIJLIJLGHJIJLHIKIJLIJLIJLGHJGHJGHJGHJHIKHIKGHJIJLHIKHIKGHJFGIFGIGHJGHJFGIEFHEFHFGIFGIFGIFGIEFHEFHFGIDEGEFHEFHEFHDEGEFHEFHDEGDEGCDFCDFDEGCDFCDFDEGBCECDFBCEABDBCEBCEABDABDABD@AC@AC?@B@AC?@B?@B?@B>?A>?A>>B>>B>>B>>B=>@<=?=>@<=?<=?<=?;<>:;=;<>;<>9:<;<>;<>;<>:;=9:<:;=9:<;<>=>@;<><=?;<><=?<=?<=?=>@<=?<=?=>@>?A=>@?>@?>@@?ABACA@B@?A@?AA@B@?ABACBACCBDBBBAAACCCCCCCCCCCCCCCCCCCCCCCCAAAAAAAAA???>>>===:::999688466244022,..,...00/11/11/11.00.00022022/11133022022133022022133*..        + + + + + + + + + + EGGEGGFHHEGGEGGEGGEGGFHHEGGFHHGIIEGGGIIEGGGIIGIIGIIGIIGIIGIIGIIGIIJLLIKKGIIIKKHJJHJJHJJHJJHJJIJLIJLJKMKLNIJLIJLJKMIJLIJLIJLJKMIJLJKMIJLKLNJKMJKMIJLJKMIJLIJLHIKJKMIJLIJLJKMJKMKLNIJLHIKJKMIJLIJLJKMIJLIJLIJLHIKHIKIJLIJLIJLIJLHIKIJLIJLGHJHIKIJLHIKIJLIJLIJLIJLHIKHIKGHJIJLHIKGHJGHJHIKHIKIJLHIKHIKGHJGHJHIKIJLHIKHIKHIKGHJHIKHIKIJLGHJHIKHIKGHJHIKHIKGHJHIKGHJFGIGHJFGIGHJGHJFGIFGIFGIGHJEFHEFHFGIFGIFGIEFHEFHFGIFGIDEGCDFEFHDEGDEGDEGDEGDEGCDFCDFCDFBCEBCEBCEBCEBCEBCEABDBCEBCEBCEABD?@B@AC@AC@AC?@B?@B?@B?@B>?A?@B>>B??C>>B==A=>@<=?<=?;<><=?:;=:;=;<>;<>:;=9:<9:<:;=:;=:;=9:<9:<9:<:;=;<><=?;<><=?;<><=?<=?<=?=>@=>@=>@>?A>?A?>@@?A@?A@?A?>@?>@@?AA@BA@BA@BA@BBACAAAAAABBBCCCBBBBBBBBBAAACCCCCCAAAAAAAAA>>>>>>===;;;777466355133022,..,...00.00/11/11/11/11/11133022022133022/11022133)++      + + +    + + +  + + CEEDFFEGGEGGEGGFHHFHHEGGGIIGIIGIIFHHEGGGIIFHHGIIFHHFHHIKKGIIHJJGIIGIIGIIGIIHJJHJJHJJHJJHJJHJJIJLHIKHIKJKMIJLJKMJKMHIKHIKIJLJKMJKMJKMIJLJKMJKMJKMIJLJKMIJLHIKIJLHIKHIKHIKJKMIJLIJLIJLIJLHIKHIKHIKJKMHIKIJLIJLHIKHIKHIKIJLHIKJKMHIKIJLIJLHIKHIKIJLIJLGHJJKMHIKIJLIJLGHJGHJGHJJKMHIKGHJHIKHIKHIKHIKGHJHIKHIKHIKFGIHIKIJLHIKHIKHIKGHJGHJGHJHIKHIKHIKGHJGHJGHJGHJGHJHIKGHJFGIGHJGHJEFHEFHGHJHIKFGIDEGEFHFGIEFHEFHEFHEFHEFHEFHDEGDEGDEGDEGDEGEFHDEGDEGDEGDEGCDFBCECDFCDFDEGCDFBCEBCEBCEABD@AC@AC@AC@ACABD?@B?@B?@B?@B>?A>?A>?A?@B=>@=>@=>@=>@<=?;<><=?;<>;<>9:<:;=:;=9:<9:<9:<:;=:;=89;9:<:;=:;=9:<:;=;<>:;=:;=;<>;<><=?=>@=>@=>@<=?<=?>?A>?A?>@?>@?>@BAC@?A@?AA@B?>@?>@@?AAAAAAABBBAAABBBBBBBBBAAA@@@AAAAAA@@@>>>>>>>>>:::999888466355133/11+--,.../1./1/11/11.00/11022133133/11133022/11244+//        + +  +  + + + + +  + +DFFEGGEGGDFFEGGFHHFHHFHHFHHFHHGIIFHHGIIEGGGIIGIIFHHGIIHJJFHHIKKGIIGIIGIIGIIGIIHJJHJJHJJIKKHJJIJLHIKHIKIJLHIKIJLJKMIJLJKMKLNKLNJKMIJLJKMIJLJKMIJLIJLIJLIJLIJLJKMHIKHIKIJLIJLIJLHIKJKMIJLHIKIJLHIKHIKHIKIJLIJLJKMJKMIJLHIKHIKHIKIJLHIKHIKJKMJKMHIKHIKGHJGHJHIKHIKHIKHIKHIKGHJGHJHIKHIKGHJHIKGHJHIKGHJHIKGHJGHJHIKHIKIJLHIKHIKHIKHIKFGIHIKHIKGHJGHJGHJGHJGHJHIKIJLHIKHIKFGIGHJFGIGHJFGIGHJFGIEFHEFHGHJEFHEFHEFHEFHFGIFGIDEGEFHFGIEFHDEGDEGCDFCDFDEGCDFDEGCDFBCECDFBCEBCEBCEBCEBCEBCEABDABD@AC@AC?@B?@B?@B>?A?@B>?A>?A>?A>?A=>@=>@?@B=>@<=?=>@;<>;<>;<><=?:;=9:<9:<9:<9:<:;=:;=89;89;9:<89;89;89;9:<9:<:;=;<>:;=:;=;<><=?<=?;<><=?<=?>?A=>@>=?>=??>@>=??>@@?ABAC@?A?>@@?ABBBBBB@@@@@@@@@@@@@@@@@@@@@@@@@@@>>>===<<<<<<:::888777577244022/11+---//./1/02/11022.00/11/11022022/11/11/11133+--   +        + +   +  + + + +  + + +  + + + + + + EHEEGGDFFEGGEGGEGGFHHFHHFHHFHHEGGFHHGIIFHHEGGFHHGIIIKKHJJFHHHJJGIIGIIGIIHJJIKKIKKGIIHJJIKKHJJIKKIKKHJJHJJIKKIKKIJLHIKIJLIJLIJLJKMIJLIJLHIKIJLJKMJKMHIKKLNHIKIJLIJLHIKHIKIJLIJLIJLHIKJKMHIKHIKHIKHIKHIKIJLHIKIJLIJLIJLIJLIJLIJLIJLHIKHIKHIKHIKGHJHIKHIKHIKHIKIJLHIKHIKHIKHIKGHJHIKHIKHIKHIKHIKIJLHIKIJLHIKHIKGHJHIKJKMGHJHIKHIKHIKGHJGHJHIKGHJHIKHIKGHJGHJIJLHIKGHJGHJGHJGHJFGIGHJGHJGHJFGIFGIEFHFGIEFHEFHFGIEFHFGIDEGEFHFGIEFHCDFDEGDEGCDFCDFDEGCDFCDFBCECDFBCEABD@ACABDABDBCEABDABDABD@AC@AC?@B>?A?@B?@B?@B?@B??C==A>>B>>B<=?=>@;<>;<><=?;<><=?;<>9:<89;89;89;9:<9:<9:<89;89;89;9:<89;78:89;89;78:9:<:;=9:<:;=:;=:;=;<>=>@;<><=?;<>=>@:;=<=?<>>;==>=??>@@?A?>@>>>?????????@@@@@@???@@@@@@@@@@@@??????===<<<<<<;;;:::888777466244022.00+--,.../1/02.00/11.00.00.00/11013/02013124*..         + + + + +  + + + + + +  + + + + + + + + + + + + + + + + + + + +DGDDFFEGGGIIFHHEGGEGGDFFFHHEGGEGGEGGDFFEGGHJJFHHFHHGIIGIIGIIGIIGIIHJJGIIGIIJLLHJJHJJIKKHJJIKKHJJIKKHJJIKKHJJIKKIJLIJLIJLHIKIJLIJLJKMIJLJKMHIKJKMJKMIJLJKMIJLHIKIJLIJLHIKHIKJKMHIKHIKIJLIJLIJLHIKIJLIJLIJLJKMIJLHIKJKMHIKIJLIJLJKMIJLJKMIJLIJLHIKIJLGHJIJLHIKHIKIJLGHJGHJHIKHIKIJLIJLHIKHIKHIKHIKIJLHIKHIKIJLGHJHIKGHJGHJHIKHIKGHJHIKGHJHIKHIKGHJGHJGHJGHJHIKHIKGHJGHJGHJGHJEFHEFHFGIFGIFGIFGIEFHEFHGHJEFHEFHFGIDEGDEGEFHEFHDEGCDFDEGDEGCDFDEGBCEBCEBCEBCEBCEBCEABDABD@AC@ACABDABD@AC?@B@AC@AC?@B?@B>?A>?A>?A>?A>>B==A==A==A;<><=?;<>;<>:;=;<>;<>:;=9:<89;89;9:<89;89;89;78:78:67978:78:67989;78:78:89;9:<89;:;=9:<:;=:;=:;=;<>:;=;<>:;=;<>;<><>>;===<>>=?>=?=<>>>>???>>>>>>???>>>>>>?????????>>>>>>>>>===<<<<<<;;;999777666244022/11,..)++-//./1./1/11/11-///11/11.00/02./1/02./1        + + + + + + +  + + + + + +   + + + + + + + + + + + + CEEEGGDFFEGGEGGDFFEGGDFFEGGFHHEGGEGGEGGGIIGIIGIIFHHFHHGIIGIIGIIFHHGIIHJJHJJIKKHJJHJJGIIHJJJLLHJJIKKIKKIKKIJLIJLJKMIJLIJLHIKIJLIJLJKMJKMLMOJKMJKMIJLJKMJKMIJLHIKIJLHIKHIKJKMJKMIJLJKMIJLIJLJKMIJLIJLIJLHIKJKMJKMIJLGHJIJLHIKIJLIJLIJLIJLHIKIJLHIKGHJHIKIJLIJLHIKIJLHIKHIKHIKIJLHIKHIKHIKGHJHIKHIKIJLJKMHIKHIKGHJIJLGHJHIKIJLHIKGHJGHJGHJHIKGHJGHJGHJGHJGHJFGIGHJHIKFGIFGIFGIGHJEFHFGIFGIFGIGHJFGIEFHEFHEFHDEGDEGEFHEFHDEGDEGDEGDEGDEGCDFCDFCDFBCEBCEABDBCEBCE@ACABDABD?@B@AC@AC@AC?@B?@B?@B>?A?@B?@B?@B<=?==A>>B;;?;;?<<@==A:=@98;>8;>9:<9:<9:<9:<89;78:78:78:89;78:78:89;78:78:56867978:56878:78:67978:9:<89;89;;<>:;=89;9:<89;9:<:;=9:<;<>:;=9:<:;=9:<;;;<<<<<<===999999888999888888888777555444333111,..+--+--*,,'))%''%''#%%"$$*,,-.0-.0/02./1.00.00/02/02./1/02+.0      + + + + +  +  + + +  + +    + + + + + +  + +  DFFCEEDFFEGGEGGEGGEGGEGGFHHFHHEGGFHHFHHFHHGIIFHHFHHFHHHJJFHHGIIFHHHJJIKKGIIHJJGIIHJJIKKHJJHJJIKKIKKJLLJLLKLNIJLIJLJKMHIKIJLHIKIJLJKMKLNJKMJKMIJLJKMIJLJKMJKMJKMJKMIJLIJLHIKIJLKLNIJLHIKGHJJKMHIKHIKIJLIJLHIKKLNIJLHIKIJLIJLHIKIJLIJLIJLHIKHIKHIKIJLHIKJKMIJLHIKHIKHIKIJLHIKGHJGHJHIKHIKIJLGHJHIKGHJHIKIJLHIKHIKHIKGHJGHJGHJGHJHIKGHJGHJHIKHIKFGIGHJHIKGHJGHJGHJGHJFGIFGIFGIGHJEFHFGIEFHEFHFGIEFHDEGEFHEFHEFHCDFEFHDEGDEGDEGCDFCDFCDFBCECDFCDFBCEBCECDFABD@ACABD@ACABD@AC?@B@ACABD?@B>?A>?A>?A=>@>?A=>@=>@==A<<@;;?<<@==A<<@8;>8;>::>;;?69<69<9:<9:<78:78:89;78:78:78:78:67956867978:679679679568568568457457124457013235235235124124013235235/02013235/02./1/02000111...---******'''(((%%%###$$$"""!!!!!!       %''+--,-/-.0./1./1-//.00/02./1013013      +    + +  + +    + + +  + +    + + + + + +   + + + DFFDFFEGGEGGEGGFHHEGGDFFEGGEGGEGGGIIEGGGIIGIIFHHGIIFHHFHHGIIHJJHJJFHHHJJGIIHJJGIIHJJIKKHJJHJJHJJJLLJLLIKKHJJIKKIKKHJJHIKJKMHIKIJLJKMHIKIJLJKMKLNJKMHIKIJLJKMIJLHIKJKMIJLIJLJKMKLNIJLIJLGHJIJLIJLIJLIJLHIKHIKHIKHIKIJLIJLIJLIJLHIKIJLHIKHIKIJLHIKIJLIJLHIKIJLIJLIJLHIKIJLIJLHIKGHJHIKIJLIJLGHJHIKGHJHIKGHJHIKHIKHIKGHJFGIFGIGHJGHJFGIHIKHIKHIKGHJGHJGGKGGKDDHEEIEEIEEIEFHEFHFGIFGIFGIEFHDDHEEIDDHEEIBEHCFIBEHBEHBEHADGAEF@DEADGADGBCEBCEBCECDF@DE?CD@DE?CD>BC>BC?CD>BC?CD=AB;>@=AB=@C;>A:=?:=?:=@;>A:=@969<8;>7:=7:=7:=7:=69<69<36836858:368257035146035146.13.13-02,/1+.0*+-)*,'*,&)+'(*'(*'(*&')'(*%&(&')&')&')%&(&((&((%''%''$&&$&&%''#%%"$$ ""!!   "$$*,,,..,..,..,-/-.0-.0./1./1/02./1         + +   +  +   +  + +    + +   + + CEEDFFDFFEGGEGGEGGEGGEGGEGGEGGFHHGIIEGGGIIFHHFHHFHHGIIFHHGIIEGGFHHFHHGIIGIIHJJHJJHJJHJJGIIIKKJLLHJJHJJGIIGIIHJJIKKHJJIJLIJLKLNIJLIJLHIKIJLIJLIJLIJLJKMJKMIJLHIKHIKIJLHIKIJLIJLIJLIJLIJLIJLGHJIJLIJLIJLHIKHIKIJLJKMJKMIJLIJLIJLIJLIJLIJLHIKGHJHIKGHJHIKHIKHIKHIKGHJGHJIJLHIKIJLGHJGHJIJLIJLHIKHIKHIKHIKGHJHIKHIKHIKGHJFGIFGIGHJFGIGHJGHJEFHFGIGHJFGIGGKGGKEEIEEIFFJEEIEFHFGIFGIFGIGHJEFHDDHEEICCGDDHBEHCFIADGADGBEHADGAEF@DE@CF@CFABDABDABD@AC>BC=AB>BC=AB>BC@:=?A8;>9<>8;=8;>:=@8;>7:=7:=69<69<47:369258258147/25,/2,/1+.0*-/'*,'*,$')$')#&(!$&!$&!$&!$&!$&!$&"#%"#%!$&!$&"#%"#%#$&"#%"#%"#%"#%!"$"#%"#%!##"$$!## "" "" ""!!        !! ""!##'))+--*,,,..+---.0-.0-.0-.0/02/02      +    +    + + +   + + +  + +  + +   + +   EGGDFFDFFEGGEGGEGGFHHEGGEGGEGGEGGHHHGGGEGGGIIEGGFHHGIIHJJGIIGIIFHHFHHGIIGIIHJJHJJGIIHJJHJJGIIHJJHJJHJJHJJIKKIKKIJLHIKHIKIJLHIKHIKIJLGHJHIKJKMIJLJKMJKMHIKHIKJKMIJLIJLIJLGHJHIKIJLIJLJKMHIKHIKHIKHIKGHJIJLHIKHIKHIKIJLIJLHIKHIKGHJIJLGHJGHJIJLHIKGHJHIKGHJHIKHIKFGIGHJGHJGHJGHJGHJGHJFGIGGKHHLFFJGGKGGKGGKGGKGGKFFJGGKFFJFFJFFJEEIFFJFFJGGKFFJBEHCFIDGJDGJCFICFICFICFIBEHBEHBEHBEHBEHCFIBEHADGADGADGADGADG@CF?BE?BE>AD>AD>AD=@C>AD>AD=@C;>A=@C=@C;>A;>@;>@:=?9<>9<>7:<58:479257368146035146-02,/1+.0(+-(+-(+-%(*$')#&("%' #%!$&"$"$"$!"$ !# !# !# "!"$!##!##!##!##!##!##"$$!##!##!##!## ""!## ""!##!## "" "" ""!##!##!##!##!##!##!## "" ""!!!!!!       !! !! """$$$&&(***,,)++*,,+--,-/,-/*-/*-/.13       +  +  + + + + + + + + + +  + + + +  + +   + + + + + + + + + + + + EGGEGGDFFEGGEGGDFFGIIFHHDFFDFFEGGGGGGGGFHHGIIFHHGIIHJJHJJHJJFHHFHHFHHHJJGIIGIIIKKHJJHJJHJJHJJHJJHJJHJJIKKHJJIKKJKMHIKHIKIJLHIKIJLIJLIJLIJLJKMIJLJKMKLNJKMIJLJKMJKMIJLHIKHIKHIKHIKIJLIJLIJLHIKGHJHIKGHJHIKGHJHIKHIKHIKIJLIJLHIKHIKGHJGHJGHJHIKHIKGHJHIKGHJGHJGHJGHJGHJGHJFGIFGIGHJGHJGHJGGKFFJGGKGGKHHLHHLGGKFFJFFJFFJFFJFFJDDHEEIFFJEEIDDHEEICFIBEHBEHCFIBEHCFIBEHADG@CF@CF?BE@CFADG@CF>AD=@C=@C?BE?BE?BE=@CA9AD@:=?:=?8;=69;8;=7:<257035035/24.13+.0),.(+-&)+%(*#&("%'!$&!#!#   !!! " " " ""$""## #%"$####"$"$!##!##!##!##!##!##!##"$$!##"$$"$$"$$"#%#$&#%%"$$#%%"$$!## "" "" ""!!    !!!!!! ""!###%%$&&')))++)++(**(***,,+--,..,/1!#              + +  +  + + + + + + + + + +  + + + +  + +  DFFDFFDFFDFFCEEDFFEGGDFFEGGFHHFHHFHHEGGEGGEGGFHHGIIGIIFHHGIIGIIHJJGIIFHHGIIFHHFHHFHHGIIHJJGIIHJJGIIHJJGIIHJJGIIHJJHJJHIKHIKGHJGHJGHJHIKHIKJKMHIKGHJIJLJKMGHJHIKHIKIJLJKMHIKIJLIJLGHJHIKHIKHIKHIKHIKGHJGHJGHJGHJGHJGHJFGIFGIDHIEIJEIJEIJDHIDHIGHJFGIEFHFGICGHCGHDHICGHEFHDEGDDHDDHADGDGJBEHADG@CFCFIBEHADGADG?BE?BE>AD>AD?BE=@C=@C;>AA8;>9AD=AB69;7:<8;=69;69;257035035.13,/1,/1(+-(+-'*,%(*"%'$')"%' #% #%!# " "!   !!!!!!""!#!#"$!#"$"$ $$ $$"$ #% #% #%## $$####"$$"$$!##"$$"$$#%%$%'$%'$%'$%'#$&#$&$%'#$&!## "" ""!##!!!!        !! ""!! ""!##!##"$$#%%$&&%''*,,*,,)++)++*,,*,,*-/),. +          + +   + + + + + + + +  + + + + +  + +      + + + +  DFFDFFCEEDFFDFFEGGEGGDFFDFFEGGDFFDFFEGGEGGEGGDFFFHHGIIEGGEGGDFFFHHFHHFHHGIIGIIFHHFHHGIIGIIHJJGIIIKKHJJFHHFHHGIIGIIHJJGHJGHJHIKGHJGHJGHJHIKGHJGHJHIKGHJFGIFGIHIKFGIGHJGHJGHJFGIDEGEFHDEGDEGEFHAEFAEFCGHCGH@DEAEFBFG@DE@CF@CF?BE>AD@CF?BE@CF>AD=@C58;369147258/25/25-03*-/+.0*-0),/&)+%(*$')"%'!$&!$& #%"$!#!# "!  !    ! !! "" "!#"$"$"$"$ $$ $$ #% #% #% #%#### $$ $$!###%%#%%#%%#%%$&&$%'%&(&')%&($%'%&($%'$%'#%%"$$ ""!##!!!!       !!!!!! "" ""!##"$$#%%%''(**(**)++)++*,,)+++--,/1       +    + + + + + + + + +   +  + + + + +  + +  + + + +    + + + + + +  DFFDFFDFFDFFDFFCEEDFFDFFDFFDFFFHHCEEEGGEGGDFFEGGFHHEGGEGGCEEDFFEGGEGGGIIDFFEGGFHHFHHFHHFHHFHHEGGGIIEFHDEGEFHEFHGHJGHJEFHDEGFGIEFHEFHEFHEFHFGIEFHDEGDEGDEGBCECDFAEF@DEBFG@DEAEFAEF@DE?CD?CD@DE>BC=AB=AB;>@;>@;>@:=?;>@7:<69;69;58:479035035-02/02-.0,-/*+-),.&)+'(*%&($%'$%'$%'"#%!"$!"$!"$ "!!!!! !        !!! "!#!#!#!#"$"$"$ #% #% #% #% #% #% #%!$&!$&#%%#%%"#%$%'$%'$%'%&(&')%&(&')&')%&(%&(%&($%'#$&#%%#%%"$$ "" "" ""!!       !!!###%%(**,..022'))$&&')))++*,,*+-*+-(+-+.0 +       + +  +  + + + + + + +    + +    + +  + + + +   + + + +       + +    DFFBDDCEEDFFCEEDFFBDDCEECEECEECEEBDDDFFDFFDFFDFFDFFDFFDFFBDDCEEDFFDFFDFFCEECEEBDDDFFCEEEGGCEEEGGEGGCDFABDBCECDFBCEBCEABDABDBCEABD@ACABDBCEBCE@AC=>@@AC?@B<=?=>@=AB:=?7:<69;58:47958:479257035/24-02-02,/1*-/'*,(+-(+-%(*$')$')"%'"%'!$& #%!#!"$!"$ !# !#!#!!  !!!!!!!   !  !           "!! "!#!#!# #% #% #% #%!$&!$&!$& #%!$&!$&!$&!$&"%'!$&$&&$&&$%'$%'$%'$%'&')&')'(*'(*()+'(*%&(%&(%&(#$&#%%"$$!##!##!##!##!!   !##')).001335777997999;;:<<<>>FHH>@@,..'))(***+-*+-),.'*,       + +  + + + + + + +    + +    + + + +     + +  + +   + +  + +   BDDBDDACCBDDBDDBDDBDDACCBDDBDDBDDBDDBDDACCBDDBDDACCBDDACCCEEBDDCEE@BBACC@BBBDDBDD@AC?@B?AA@BB?@B>?A>?A>?A>?A<=?;<>=>@=>@:;=;<>9:<78:568568457235124013./1./1/02-.0+,.*+-)*,(**&(('))&(($&&#%%#$&"#%"#%!"$!"$!"$ !# !# " " " " "!! "!!! "! "!  !!!!  !!   ! !  !             ! !  " "! "!#!# #% #% #% #%!$&!$&"%'!$&!$&"%'"%'"%'"%'"%'!$&%''$&&%&(&')$')$')'(*&')'(*()+&)+%(*%&('(*'))%''%''%''#%%!##!## ""  !!!##%''.002444664663555774664664664666888::CEEQSSIKK799.00*,,,-/     + + +  + + + + + +   +  + + + +      + +  + +  + + + + + + BDD?AA?AA>@@@BB@BB>@@>@@ACC?AA>@@?AA?AA=???AA=???AA=??<>>=??;==;==;==:<<<>>:<<68867978:577466457235124/02/02/02./1./1,-/*+-*+-()+()+'(*&')%&(%&(#$&%&("#%"#%!"$!"$!"$!"$"#% "" "" ""!!!!!!!! "!!!!!!!!!!!!!! " "!! " "!!!!!!!  "!! !!!!! !!!! !           !!!! "!#!#"$"$"$"$ #%!$&!$&"%'"%'!$&"%'"%'"%'"%'"%'#&("%'%''$&&%&(&')%(*%(*'(*'(*()+)*,%(*&)+)*,+,.-//,...00/11/11/11022133.00,..*,,$&&"$$!##"$$%''%''*,,.00022022244466466466355355577577799799=??KMMSUUOQQIKK)*,      + + + + + + + +  + + +  + + + + + +     + +  + + + +   ;==;==;==;==;==;==;==:<<8::7998::799577799466688355244355/11/11022.00,..+--*,,)++)++)++(**&((&((%''$&&$&&$&&$&&!##"$$"$$!##!## ""!!!!!!!!!!!!!!   !!    !!  !!!!      !!!!!! "!! " " " "! " "! " " "!! "! "!!!! "! " "!!  ! !!        !      !  ! "! "!# "!#!#"$"$ #% #%!$&!$&!$&"%'"%'#&(#&($')$')$')"%'"%'#&(#&(#&(%(*%(*&)+&)+&)+&)+*+-'(*()+./1/02,-/-.0,-//11133244577799799:<<=??@BBACCCEEDFFCEE?AA8::244/11.00/11133244466244244355577466688688799<>>HJJTUWQRT   + + + + + + +  + + + + + + +  + + + +  + +     + + + + + +  + +  + +  466355577355133/11/11.00.00-//,..,..,..)++')))++'))%''%''$&&#%%#%%"$$!##!##!##!##!## ""!! "" "" ""!!!!!##!!!! !!  !!     !! !!     !! !!!!!!!! ""   !!!!!! !#!! !# !#!! "! "!!! " "! " " " "!! "! " " " " "!! "! "!! !!!!!! "! ! !!            ! !!! "!#!#!#!#"$ #% #% #%!$&"%'"%'"%'"%'#&(#&(#&($')$')#&(#&(#&($')%(*%(*&)+&)+'*,&)+'*,()+()+-.0013346/02-.0-.0.00/11/11244355577688:<<9;;9;;=??DFFBDDACCDFFEGGGIIEGG=??466133244355355355466466577799799688:<>>@@GIIDFF?AA7993551332443552444665776888::466     + + + + + +   + + +  + + + + + + + +  + + + + + +  + +   + + + + + + + +   + + + + + + !##!! !!  !!!!        !!    !! ""!!   !!!!!!  !!!! ""!! "" ""!!!!!!!! "" "" ""!! ""!!!!!!!#!# "!#!#!#!#!#!#!#"$!#"$!# !# "!#"$"$"$"$!#!# "!#!#!"$ !#!#!#!#!#!#!#!#!#"$!#!#!#!# " "!#!#!#!# "!#! "!# " " " " " "!# "!!!!!! !!           !  !!!!! " "!#"$"$"$"$"$ #%!$&"%'"%'"%'#&($')#&($')$')#&($')$')$')$')$')%(*$')%(*%(*'*,'*,&)+*-/035257457346457568457235244244244244244355466799466799CEEIKKHJJ@BBACCEGG:<<6886886889;;>@@EGGGIICEE9;;4662443553554669;;!!      + + + + +  + +   +  + + + + + + + + + + +  + + + + + + + + +    + + +          !!    !!!! "" ""!!  !!!!!! "" ""!!!! ""!!!! "" "" "" "" "" "" ""!! "" "" "" "" ""!##""##!#"$!#"$"$!#!#!#"$"$ #%"$"$"$"$"$"$!#!#"$"$"$!#!#"$"$!#"$!#!#!#"$"$"$"$!#!#!#!#!#!#"$"$!#"$!#"$!#!#!#!#!#!# "!# "!# "!!! " "!!!! "      !             !!!! " "!#!# " ""$ #% #% #%!$& #%!$&"%'$')#&(#&(%(*$')%(*%(*$')$')$')%(*%(*$')%(*$')$')&)+'*,'*,'(*-.034634645767956878:78:457244355466355244355466688577;==DFFKMMHJJACC:<<@BBDFF?AA8::6886886887999;;?AAFHHHJJFHH;==577799466    + + + + +  +  + +  +  + + + + + + + + + + + + + +  + +               !!!!  !!!!!!   !!!! ""!!!!!!!! "" "" "" "" "" ""!!!!!!!!!## "" "" ""!## "" "" ""!##!##!##!##!##!######"$"$!# #%"$"$"$"$ #% #%!#"$"$!#"$"$"$ #%"$"$"$ #% #% #% #% #% #%"$!#!#!#"$"$"$"$!#"$"$"$"$!#"$"$!#"$"$!#"$"$!#!#!#!#!#!#!#!# " " "! " " "!!!! !    "!      !    !! ! ! " "!! " " "!#!#"$"$ #%!$&!$&!$&"%'"%'#&($')%(*%(*%(*%(*%(*$')%(*$')%(*%(*&)+$')#&(#&($')%(*%(*()+,-/23556867978:89;89;9:<568466466577688688577466688799>@@BDDIKKHJJ>@@9;;;==?AABDD?AA<>>577466466577577577799;==?AA:<<:<<(**   +  +  +     +     + +     + + + + + + +  + + + +  + + + + + +               !!   !!!!!!!!!! "" "" ""!! ""!! "" ""!! "" ""!! ""!!!## "" ""!##!##!## ""!## ""!##!##"$$!"$!"$!##!##!##!##"$$"$$"$$"$$"$ #%"$ #% $$ $$ #%!$&!$& #%"$"$ #% #% #% #%"$"$ #%!$& #%"$!$& #%!$&!$&!$&!$& #% #%"$ #% #% #%"$ #% #% #%"$ #%"$"$"$"$"$"$ #%"$"$ #%"$"$"$!#!#"$"$!#!#!#!#!# " " " " "!!! "!!!!  " "!  !!!!   !!! "! "! " " " "!#!#"$"$"$ #%"$!$&"%'"%'#&(#&($')$')%(*$')$')%(*%(*%(*%(*%(*%(*$')%(*$')#&("%'"%'%(*&)+)*,,-/01378:89;78:89;9:<<=?89;6795686887999;;8::7996888::?AAABDDEGIJL=>@8:::<<;==<>><>>@BB?AA466466577466355355355466355799  + +          + +   + +   + + + + + + + + +             !!!!!!!!!!!! !! ""!!!! ""!## "" ""!! "" ""!## "" ""!## "" ""!##!##!##!##!##"$$!##"$$!##"$$"$$!##!##"$$"$$!##"#%"#%"$$"$$!##!##"$$"$$"$$"$$!$&!$&!$&!$&!%%!%%!$&!$&!$&!$&!$&!$&!$&!$&!$&!$& #%!$&!$&!$&!$&!$&!$& #%"%'!$&!$&!$&!$& #%!$&!$&!$&!$& #%!$&!$&!$&!$&!$& #% #% #% #% #% #% #% #% #%"$"$ #% #% #%!#"$!#!#!#!#!#!#!#!# "!#!#!#!# " " " " " "!! "!  !!!!! " " "!! " " " " " " " "!#!#"$"$"$!$& #%!$&!$&#&($')$')%(*%(*%(*%(*%(*%(*&)+%(*%(*%(*%(*$')$')#&("%'!$&$')'*,(+-,-/./11245689:<:;=9:<:;=<=?:;=78:568799688:<<:<<7996889;;=??CDFHIKOPRSTV>@@9;;:<<<>>>@@@BBIKKDFF244466355244133133133022244 + +    + +    + +      + + + +  + +  + + + + + + +       !!   !! !! !! ""!!!! "" "" "" ""!!!! "" "" "" "" ""!"$ !# ""!## "" "" """$$!## ""!## ""!##"$$!##!##!##!##"$$"$$"$$#%%!##!##"$$#%%"#%"#%#$&#$&"$$"$$#%%"$$#%%#%%#%%#%%#%%#%%"&&!%%!%% $$!$&!$&!$&"%'!$&!$&!$&"%'"%'!$&!$&"%'"%'"%'#&(!$&"%'"%'"%'"%'"%'"%'!$&!$&!$&!$&"%' #% #%"%'"%'!$&!$&!$&!$&!$& #%!$& #%!$&!$&!$& #% #% #% #% #%"$ #%"$!#"$"$!#"$"$"$!#!#!#!#!#!# " " "!#!#! " "!!!! "!! ! "! " " " " " " "!#!#!#!#"$"$ #%"$ #%!$&"%'"%'!$&#&($')$')%(*&)+&)+&)+&)+'*,&)+&)+%(*%(*%(*#&($')#&("%'#&(%(*(+-),.-.0/02235568:;=:;=89;:;=<=?=>@;<>568577577466577577688:;=@ACGHJJKMNOQTUWXY[LMO<>>=??>?ABCEHIKLMO;==244355244244133133/11022 + +  + +   + +    + + + + + + + + + + + + + + + !!!!!!!!   ""!!!!!!!!!! "" "" ""!! ""!##!##!! "" "" ""!##!## ""!"$"#%!##"$$"$$"$$"$$"$$!##!## """$$"$$#%%"$$#%%#%%"$$#%%#%%"$$#%%"$$#%%#%%#%%"#%$%'#$&#$&"$$#%%$&&#%%$&&%''$&&#%%%''$&&"&&"&&"&&"&&"%'"%'"%'#&("%'"%'"%'"%'"%'"%'"%'"%'"%'"%'!$&"%'"%'!$&"%'"%'#&("%'"%'"%'"%'#&("%'!$&!$&"%'"%'"%'!$&"%'!$&"%'!$&!$&!$&!$&"$ #% #% #% #% #%!$& #% #% #%"$ #% #%"$"$!#"$"$!#"$"$"$!#!#!#!# "!# "!#!#!#!# " "!# "!! "! "!# "!#!#!#!#!#!#!#"$"$"$"$ #%!$& #%!$&!$&#&(#&($')%(*%(*%(*'*,'*,'*,&)+&)+&)+%(*%(*%(*$')$')"%'"%'#&('*,(+-),.+.0./1/02346679;<><=?;<>9:<;<><=?<=?78:577577466355466799=>@EFHIJLMNPMNPOPRQRTUVXSUUEGGABDEFHFGIEFHJLL577244466244133/11.00/11   + + + + + +  + + + +   + +   + + + + + + + + + !! !!!!!!!!!!!! "" "" ""!!!! "" ""!##!##!##!## "" "" ""!##"$$"$$"$$!##"$$"$$#%%"$$"$$#%%#%%"$$"$$#%%#%%$&&"$$#%%"$$"$$#%%$&&$&&"$$"$$#%%#%%$&&$%'#$&$%'$%'$%'$%'#$&$%'$&&#%%%''$&&$&&%''"&&"&&$&&$&&#''"&&#&(#&("%'#&("%'"%'#&(#&("%'#&(#&(#&("%'"%'"%'#&("%'#&("%'"%'"%'"%'"%'"%'"%'#&(#&(#&("%'!$&!$&#&("%'"%'"%'"%'"%'!$&!$&!$&!$&!$&!$&!$&!$&!$&!$&!$&!$& #%"$ #% #% #% #% #% #% #%"$"$"$"$!#"$"$!# "!#!#!#!#!# " " " " "! " " "!#!# "!#!#!#"$!#!#"$ #% #% #% #%!$&!$&!$&!$&#&(#&($')&)+%(*&),&),&)+'*,'*,'*,'*,&)+$')$')%(*$')#&(#&("%'%(*(+-(+-*-/,/1-02/244576799:<>?A>?A;<>;<>:;=;<>;<>78:78:5683466889;;BCEIJLNOQOPRLMOKLNJKMKLNMNPPQSLMOHIKFGIDEGFGIEFH244355244133/11.00.00 + + + + + + + + + + + +  + +  + + + + + + + + + + +  !!!!!! "" "" "" "" "" ""!##"$$"$$!##!## """$$!##!##!##!###%%"$$"$$"$$!##"$$"$$"$$#%%#%%"$$"$$#%%"$$$&&#%%#%%#%%#%%#%%$&&#%%#%%#%%%''%''$&&$&&$&&%''%''$%'$%'%&($%'$%'$%'%&(%&(%''%''%''$&&$&&%''#''#''$&&$&&$((#''#&(#&("%'"%'$')$')#&($')#&(#&(#&($')$')#&(#&(#&("%'#&(#&(#&("%'#&(#&(#&("%'#&($')$')"%'#&(#&("%'"%'#&(#&("%'"%'"%'"%'"%'!$&"%'!$&!$&!$&!$&!$&!$&!$&!$& #% #%"$ #%!$&"%'!$&"$"$ #%"$"$!#"$"$"$"$!#"$!#!#!#!#!#!#"$!#!# "!#!# " "!#!#!#"$ #% #% #% #% #%!$& #%!$&!$&"%'#&(#&(#&($')%(*%(*&)+'*-'*-(+-(+-'*,(+-'*,&)+&)+%(*%(*$')#&("%'%(*),.),.*-/*-/,/1-02035457679:;=ABDABD>?A:;=9:<;<>;<>9:<9:<6794578::=??GHJJKMKLNKLNJKMKLNLMOMNPLMOOPRNOQOPRLMOEFHDEGHIK799022022/11,..-//.00  + + + + + + + + +    + + +    "" "" ""!##!##!##!###%%!##!##"$$"$$"$$!##!##"$$#%%"$$"$$#%%#%%#%%#%%"$$#%%"$$#%%#$&#$&$%'$%'#%%$&&#%%#%%%''$&&$&&%''$&&$&&%''%''&(($&&%&($%'%&($%'%&($%'&')%&($%'&')%&(%&(%&(%&(&')%&(#''#''%''&((#''$((%''&(($((%))$')#&($')$')#&(#&(#&(#&($')$')$')$')#&(#&($')$')$')$')$')$')#&(#&($')$')#&($')$')$')#&(#&(#&(#&(#&(#&(#&("%'"%'"%'"%'"%'"%'"%'"%'"%'"%'!$&"%'!$&!$&!$& #% #%!$&!$& #%!$&!$& #% #% #%"$ #%"$ #%"$!#"$"$"$"$"$!#"$"$!#!# "!#!#"$"$"$!#!#!#!#"%!$' #&!$' #&!$'!$&!$&"%'"%'#&(#&($')$')%(*&)+&),&),'*-(+.),/),/(+-'*,&)+&)+&)+$')$')#&("%'$')'*,),.),.*-/+.0,/1-02/2434678::;=?@BBCEABD;<>9:<89;78:9:<89;5686799:>?ABCECDF?@B:;=78:78:89;78:56889;:;=JKMVWYRSURSURSURSUPQSQRTOPROPRNOQMNPMNPMNPKLNLMOFGIGII:<<*,,*,,*,,)++*,,$&& + + + "$$"$$"$$"$$"$$!%%"&&!%%!%%!%%!%%$&&$&&#%%#%%#%%#%%#%%#%%$&&#%%$&&$&&$%'$%'$%'$%'%&($%'%&(&')%''$&&%''&((%''%''%''%''%''&((&((&((&((&((&')&')&')&')&')'(*&')&')&')&')'(*&')'(*()+'(*'(*%(*$')'*,%(*%(*%(*$')%(*%(*%(*%(*&)+%(*%(*%(*&)+%(*&)+%(*%(*%(*&)+&)+%(*%(*%(*%(*%(*%(*%(*&)+&)+$')%(*&)+%(*%(*$')$')$')$')%(*$')$')$')$')$')$')$')$')$')#&($')#&($')$')"%'"%'#&("%'"%'"%'!$&"%'#&(#&("%'!$&!$&!$&!$&!$&!$&!$&!$& #%!$&!$& #% #% #% #%"$ #% #%"$ #% #% #%"$ #% #% #& #&!$' #&!$'!$'!$'!$'!$'!$'"%'"%'"%'$')$'*%(+%(*%(*'*,'*,),/(+.(+.),/),/(+.(+-(+-'*,&)+%(*%(*#&($')'*,'*,),.),.*-/,/1-02/24/241466799:<=>@>?AABDCDF?@B<=?78:6796795689:<<=?<=?BCEMNPKLNILOKNQJNOJNOKOPKOPLMOLMOMNPMNPKLNKLNKLNLMOJKMIJL.00(**(**)++*,,2443558::?AADFFDFF@BB9;;-//!! + + +    #%%"$$#%%$&&$&&"&& $$"&&"&&!%%"&&$&&$&&$&&$&&$&&$&&$&&$&&$&&%''$&&%''$%'%&($%'$%'%&('(*$%'&')&((%''%''&((%''%'''))&((%'''))'))'))%''&((&')()+'(*&')'(*&')'(*()+'(*'(*'(*'(*'(*'(*'(*'(*%(*&)+&)+%(*%(*%(*'*,&)+&)+&)+%(*$')&)+&)+%(*%(*&)+'*,&)+&)+&)+&)+%(*&)+&)+&)+%(*&)+&)+&)+&)+%(*$')%(*%(*%(*%(*%(*%(*$')$')%(*%(*$')$')$')$')%(*%(*%(*$')$')$')$')$')$')$')$')$')#&("%'"%'"%'"%'"%'"%'#&("%'"%'"%'"%'"%'!$&!$&!$&!$&!$&!$&!$& #%!$&!$&!$&!$& #%"$ #% #% #% #%"$ #%"%(!$' #&!$'"%(!$'"%("%("%(#&)#&($')$')$')%(+&),%(*'*,'*,(+-(+.),/),/),/*-0),/(+-(+-'*,&)+%(*%(*$')'*,(+-),.),.),.*-/+.0.13/2414658:78::;==>@>?A@ACDEGEFH>?A89;679568679;<><=?<=?>?A@ACDEGCFICFICGHFJKFJKIMNJKMIJLIJLKLNHIKHIKJKMLMONOQOPREGG244799:<<8:::<;>@@ACEFHEFHABD:;=679568;<>>?A=>@<=?>?A=AB>BC?CD?CD?CD@DEBFGBFGDHIEIJEFHDEGDEGEFHEFHDEGFGIGHJ#%%#%%(**022BDDJLLKMMGIIDFFCEE@BB<>>799355+--$&&"$$!! + + + + + +  257035-02,/1+.0*-/),.'*,'*,&)+&)+$')#&($')$')#&(#&(&')'(*&')&')$')$')'(*%&(&')&')%(*%(*&')&')'(*'(*()+'(*'(*'(*()+)*,()+()+'(*()+()+'(*'(*'(*'(*'(*()+*+-()+()+()+()+&)+&)+()+()+&)+&)+%(*&)+'*,'*,'*,'*,'*,&)+&)+'*,'*,'*,'*,'*,'*,&)+'*,'*,'*,(+-(+-'*,&)+'*,'*,'*,'*,&)+'*,&)+%(*&)+&)+&)+&)+&)+&)+%(*&)+%(*&)+'*,&)+%(*%(*&)+%(*%(*&)+%(*$')$')%(*$')%(*%(*$')%(*$')$')$')#&($')$')$')$')"%'#&(#&($')#&)"%(#&)"%(#&)"%(!$'"%(!$'"%(!$'"%( #%"%' #%!$&"%'"%'"%(!$'"%("%(#&)$'*"%("%(#&)#&)$'*$'*$'*$'*$'*$'*$'*$'*%(+&),'*-&),(+.),/),/),/*-0+.1*-0),/(+-),.(+-%(*%(*&)+(+-(+-),.),.*-/+.0+.0,/1.1325736847958:58:8;=@78:78:>?A?@B>?A?@B?@B=AB>BC=AB=AB>BC>BC>BC>BC?CD@DEABDABDBCE@AC?@B=>@;<>9:< + + +  + + + + + + ;BG;BG;BG:AF8?D5@?CD@DECDF@AC<=?78::;=>?A=>@<=?;>@=AB;>@=AB=ABBC@AC?@BABD?@B>?A=>@;<>:;=9:<568 + + +      + + + + + + + OV[MTYKRWLSXKRWHOTELQDKNAHK@EH@EH?DG>CF69;69;368368257035-02-02-02,/1*-/(+-(+-(+-)*,()+&)+'*,'*,&)+'*,'*,&)+'*,'*,&)+(+-(+-(+-(+-(+-'*,'*,'*,'*,'*,)*,*+-(+-(+-(+-(+-),.(+-(+-(+-'*,'*,(+-(+-(+-'*,(+-*-/(+-(+-(+-(+-(+-),.),.(+-(+-(+-),.(+-(+-(+-(+-(+-(+-(+-(+-(+-(+-(+-(+-(+-'*,(+-(+-(+-(+-(+-'*,(+-'*,(+-'*,&)+'*,&)+&)+%(*&)+'*,'*,%(*&)+&)+%(+%(+&),%(+%(*&)+&),$'*$'*$'*%(*%(*%(+%(+$'*#&)#&($')$'*$'*$'*#&)$')#&(#&)#&)#&)"%(#&)$'*#&)#&)"%(#&)#&)$'*$'*$'*$'*$'*#&)$'*%(+%(+&),&),%(+%(+(+.'*-'*-(+.(+.),/),/),/*-0*-0+.1+.1*-0(+.'*,&)+%(*(+-(+-),.),.(+-*-/*-/+.0+.0,/1-02/2414636836858:69;7:<:=?=AB@DEBCE?@B:;=6799:<<=?<=?<=?;>@;>@9<>:=?;>@=AB=AB;>@@=>@<=?:;=:;=78:67978:013 + + + +     + + + + + + + + +   T[dT[dU\eV]fV]fV]fV]fV]fSZcSZcPW`OV_MT]LSZLSZIOVIOVHNUDJQCIP@FM@DJBFL@DJ?CI;?E8:=@=@C?BE@CF=@C69;3684797:<8;=9<>9<>;>@:=?9<>:=?:=?;>@;>@;>@@=AB9<>7:<679679568457457,-/ + + + +      + + +  + + + + + +  + + + T[dT[dV]fV]fX_hY`iX_hY`iZajZaj[bk\cl\cl[biZahY_fY_fZ`gZ`gW]dTZaTX^TX^TX^SW]OSYNRXNSVJORMPSILOGJMFILCGH@DE>BC=ABAD?BE>AD:=@4790353684797:<7:<8;=9<>9<>9<>9<>:=?:=?;>@:=?:=?7:<58:479368346235235124235'(* + + + + + + +    + + + + + T\gV^iV^iW_jX`kX`lX`lZbn[co[co[co\dp\dp\dp\dp]eq]eq^fr_gs_epagr_epagr_ep^do^do_ep]dmZaj[`jY^hX^eV\cTZaU[bRX_OU\JPWJPWKOUHLREIOBFLAFI?DG?BE?BEA>AD>AD69;257346346124235013013013/02013"#% + + + + + + + + + +  + + + +  + + + +           V^iW_jX`kX`kYal[co[co\dp\dp\dp_gs^fr_gs_gs_gs`htaiu`ht`htagrcitbhsekvekvekvekvflwgnwhoxkpzlq{jpwiovhnugmtgmtcipagn_el`dj^bh]ag[_eZ_bW\_Z]`X[^RUXPSVNQTKNQHLMFJKCGHBFG>BC=AB9<>7:<479257035035-03-03+.1+.1+.1+.1,/2+.1+.1*-0+.1,/2+.0*-/,/1+.0+.0,/1,/1,/1,/2+.1+.1,/2,/1+.0*-/+.0+.0,/1+.0+.0+.0+.0*-0*-0+.1+.1+.1*-0+.1*-0*-0*-0),/(+.),/*-0),/*-0),/'*-(+.(+.(+.(+.(+.'*-(+.(+.(+.(+.(+.'*-&),'*-(+.'*-'*-'*-'*-&),&),&),&),%(+%(+%(+'*-&),&),&),%(+%(+%(+&),&),&),'*-'*-&),&),'*-&),'*-'*-(+.'*-(+.(+.(+.*-0),/(+.),/+.1+.1*-0+.1,/2,/2,/2),/*-0(+.&),*-0*-0),/),/),/),/),/*-0+.1*-0*-0,/2,/2-03-03-03.14-03/2525858;7:=;>A;>A:=@7:=03503525736847969;69<7:=7:=969;257035035124124124124013013./1-.0/02 !# + +**(((&!! + + + + + + + + + + + + + + + + + + + + + + + + +     + + + +       YamX`lZbnZbn[co[co\dp\dp_gs_gs_gsaiuaiuaiuaiuaiu_gschuchuejwchudivdivfkxglyfkxglyglyin{jo|kp}kp}kp}lq~mrms~ms~ms~ms~ms~lr}kq|ioziozhnyekvcitbirahq_dn^cm]cjY_fX^eW]dTZaPV]MQWMQWJNTHLRGKQBFLCFI@CF;>A8;>69<369369036/25.14-03-03,/2,/2-03,/2+.0-02-03,/2,/2,/2+.1,/2,/2+.1,/1,/1+.1+.1+.1+.1,/2+.1*-0+.1+.1*-0+.1,/2+.1,/2*-0*-0),/*-0),/),/*-0+.1+.1),/),/),/),/),/+.1),/(+.(+.(+.(+.(+.'*-(+.(+.(+.&),'*-'*-'*-'*-(+.(+.&),%(+&),&),&),%(+&),&),&),&),&),&),'*-'*-&),'*-'*-&),'*-(+.(+.(+.(+.(+.(+.(+.(+.),/),/(+.*-0+.1*-0+.1,/2,/2,/2+.1*-0'*-&),'*-*-0),/*-0*-0(+.(+.),/*-0+.1*-0*-0,/2,/2,/2,/2,/2,/2,/2,/1.1314747:9A97:=8;>58;479035035/24013124235013/02/02./1-.0/02 " + + + ''%,,*((&&&$   + + + + + + + + + + + + + + + + + + + + + + + + +      + + + + + +  + +      + +   Zbn\dp]eq[co^fr\dp]eq_gs_gsaiuaiuckwckwbjvbjvckwbjvdivdivfkxfkxglyhmzglyin{in{hmzjo|kp}lq~mrmrmrmrlq~ntou€ntou€ou€ou€qw‚rxƒpvqw‚sy„v|‡szƒt{„rwrwqw~lrykqxlryhnugmtfjpfjpdhnaek_ci^bh\_bX[^X[^UX[RUXNQTKNQILOFILCFI@CFADA8;>58;47:258036.14.14-03-03,/2-03-03-03-03.14-03-03-03,/2,/2+.1,/2,/2+.1-03+.1,/2,/2*-0+.1*-0*-0*-0*-0*-0),/),/*-0),/),/),/),/),/),/(+.(+.(+.),/(+.'*-'*-(+.(+.(+.),/),/),/(+.'*-(+.(+.(+.),/),/),/(+.),/),/*-0*-0+.1+.1*-0+.1+.1,/2,/2,/2+03*/2,/2*-0'*-$'*#&)&),),/),/(+.),/),/),/),/*-0),/+.1+.1+.1+.1+.1*-0+.1,/2+.1*-0*-0,/2+.1*-0*-0/25,/2-0303603503525736825758:7:<479257146257368146146479368257035.13-02./1-.0/02 + +((&++)..,''%((&((&((& %%#//- +**(##!&&$  + + + + + + + + + + + + + + + + + + + + + +  + + + + + + + + + + + + + +  + + + + + + + +  + +   + + + bgtbgtdivdivejwejwejwejwejwejwfkxfkxejwfkxglyglyfkxhmzhmzin{jo|kp}jo|jo|lq~lq~mrns€pu‚pu‚pu‚qvƒpu‚qvƒpu‚qvƒrw„qvƒsx…rw„ty†ty†ty†ty†ty†ty†ty†ty†v{ˆv{ˆw|‰x}Šx}Šy~‹zŒx€Œyw‹yx€Œy{€{€{€{€||}‚‘„“|Ž~ƒ|Ž}‚zŒw|‰uz‡ty†rxƒqw‚ou€lr}lq|mr}jozinyhmwfkubho`fm]ah^biY]dY]dSW]QU[MQWIMSGKQCGM<@F;?E6;>38;369147/25.14.14-03,/2-03,/2,/2+.1-03,/2,/2-/5,.4,.4,.4-/5,.4+-3+-3*-0*-0*-0+.1),/+.1+.1+.1),/*-0*-0),/),/),/(+.),/),/(+.(+.(+.),/),/),/),/),/),/(+.),/),/),/*-0),/),/),/+.1),/),/*-0*-0+.1*-0+.1+.1+.1,/2+.1*/2).1).1',/$),"'*"%($'*&),(+.'*-(+.*-0),/*-0),/),/*-0*-0*-0),/*-0),/*-0*-0*-0*-0+.1*-0),/(+.(+.(+.'*-'*--03.14/2503625825847:4793682573682574797:<9<>7:=69<368035/24-02-02+.0-02 + + + + +  ))'$$"((&$$" ,,* ##!##! + + + + + + + + + + + + + + + + + + + + + + + + + +  + + + +  + + + +  + + + +  + + + + + + + +   + + + + + + + +  + +ejwdivejwfkxejwfkxglyglyfkxfkxhmzglyglyglyhmzglyhmzjo|jo|jo|in{lq~lq~kp}lq~lq~mrpu‚ototpu‚qvƒrw„rw„qvƒrw„rw„sx…uz‡ty†ty†uz‡ty†uz‡v{ˆuz‡ty†uz‡w|‰w|‰w|‰x}Šy~‹y~‹zŒy{ƒx€Œz‚Žyy{€{€{€|{€||}‚‘„‘}‚„‘~ƒ}‚„‘†“€…’‡’…€†‘~„„}‚zŠy~‰x}‡uz„tzrxsw~rv}oszmqxjntgkqeiocgm^bhZ^dX\bTX^SX[NSVORUMPSHKNDGJ?BE69<58;369258/25-03,/2,.4-/5,.4,.4-/5-/5+-3-/5,/2,/2+.1,/2,/2+.1*-0+.1*-0*-0*-0*-0*-0),/),/),/),/*-0),/(+.),/*-0*-0(+.(+.(+.),/*-0*-0*-0*-0*-0*-0),/+.1*-0+.1+.1+.1+.1+.1,/2+.1+.1,/2+.1*/2(-0(-0&+.$),"'*"%(#&)&),&),'*-'*-),/),/*-0),/),/+.1*-0*-0),/*-0),/),/*-0*-0),/(+.(+.(+.(+.'*-'*-&),&),),/.14/25/2514725825847936847958:69;7:<9<>9<>98;>7:=8;>:=@58;146146035.13,/1+.0.13 + + + + + + + + + + + + + +  + %%# ##!$$" + + + + + + + + + +  + + + + + + + + + +  + + + + + + + + + + + + + + + + + + + + + + + + + + + + iozglyhmzhmzglyhmzin{hmzin{in{in{in{jo|jo|jo|kp}jo|jo|jo|mrmrmrlq~mrns€ototpu‚pu‚rw„qvƒqvƒrw„ty†ty†sx…ty†uz‡ty†v{ˆv{ˆuz‡w|‰x}Šw|‰w|‰v{ˆx}Šy~‹x}Šy~‹zŒ{€}‚|Ž|Ž}‚~ƒ}‚~ƒ~ƒ„‘}‚„“„“~ƒ’~ƒ’„“€…”†•€…”€…”€…”†•€…”€…”†•‚‡–†•ƒˆ—†•‚‡”‚‡”ƒˆ•ƒˆ•ƒˆ•„‰–…Š—„‰–„‰–‡Œ™‡˜†Œ—‡˜…‹–…‹–ƒ‰”‡’~„|‚x~‰w~‡t{„v{…sx‚rwot~kqxhnuflscipdhoael^bh]agX\bVZ`RV\PTZOQWJLRHJPDFL@BH;=C9;A68>139/17/25.14-03+.1,/2+.1*,2,.4+-3+-3+-3,.4,.4,.4+.1+.1+.1*-0+.1,/2+.1+.1*-0+.1,/2+.1*-0+.1,/2+.1,/2,/2+.1+.1-03-03,/2+.1+.1+.1).1*/2*/2(-0',/#(+&),$'*"%("%(&),&),&),&),(+.(+.),/),/(+.(+.),/),/*-0),/(+.(+.*-0),/*-0'*-'*-'*-&),&),&),'*-'*,'*,),/,/2.14.14/2525858;58;69<7:=98;>9DK>BI:>E7;A48>15;.28,06*.4*.4+/5+/5)-3)-3(,2)-3(,2*,2+-3+-3*,2+-3,.4*.4)-3(,2)-3)-3)-3+/5+/5)-3*.4*.4+/5*.4*.4)-3*.4*.4*.4*.4(,2&*0#'-%(+$'*"%("%($'*&),%(+&),(+.(+.),/(+.'*-),/),/(+.(+.(+.(+.*-0),/),/%*-#(+%(+&),&),&),&),'*-&),%(+&),+.1.14-03.1403658;7:=8;>8;>:=@8;>7:=7:=7:=47:/24/24/24-02-02,/1.13 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +lr}ns€lq~otns~nrnros€nrlp}nrnrlp}mq~lp}mq~mq~nrnros€os€os€qu‚ptptqu‚qu‚rvƒrvƒrvƒtx…tx…sw„sw„tx…tx…vz‡v{ˆw|‰w|‰w|‰y~‹y~‹x}Šx}Šy~‹zŒzŒ{€|Ž|Ž}‚|Ž}‚‘~ƒ’}‚}‚„‘€…’„“„“€…”„“€…”€…”€…”†•†•€…”‚‡–ƒˆ—‚‡–ƒˆ—‚‡–„‰˜„‰˜„‰˜ƒˆ—„‰˜„‰˜„‰˜…Š™„‰˜ƒˆ•…Š—…Š—…Š—…Š—‡Œ™…Š—†‹˜„Œ˜…™ƒ‹—…™„Œ˜…™„‹š„‹šƒŠ™ƒŠ™ƒŠ™ƒŠ™ƒ‹—„Œ˜„Œ˜ƒ‹—„Œ˜„Œ˜…™€ˆ”‰•‰•}…‘z‚Žz€‹w}ˆu{†sy„qw‚qw‚pvkq|hoxgnwgmtdjq_el^dk\biW]dX\cRV]QU[MQWKOUHLRDHNCGM=AG9=C59?37=15;/39.28+/5,.4,.4+-3+-3+-3-/5*.4)-3)-3+/5*.4)-3*.4*.4)-3*.4*.4+/5+/5,06,06*.4*.4+/5*.4(,2&*0%)/%(+$'*"%(!$'$'*$'*%(+'*-'*-(+.(+.),/(+.(+.(+.),/),/(+.),/),/(+.(+.$),%*-%(+&),'*-'*-'*-&),'*-&),%(+'*-,/2-03.14.1458;7:=969<7:=7:=7:=47:035/24.13-02,/1+.0,/1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + otpu€otqvotptos€qvpu€pu€rw‚pu€otns~otns~pu€otpu€os€ptotqvqvqvrw‚sxƒsw„tx…tx…tx…tx…tx…tx…uy†vz‡w{ˆw{ˆvz‡w{ˆx|‰y}Šy}Šz~‹{Œ{Œ|€|€}Ž}Ž~‚}‚~ƒ|Ž~ƒ~ƒ’~ƒ’„“„“„“~ƒ’€…”„“€…”†•‚‡–‚‡–†•ƒˆ—‚‡–ƒˆ—„‰˜ƒˆ—„‰˜…Š™„‰˜…Š™„‰˜…Š™…Š™…Š™…Š™†‹š†‹š†‹š‡Œ›…Š™‡Œ™‡Œ™‡Œ™‡Œ™…™†Žš…Œ›„‹š„‹š…Œ›ƒŠ™„‹šƒŠ™ƒŠ™ƒŠ™„‹š„‹š„‹š„‹š„‹šŠšŠš€‰™‚‹›‚‹›‚‹›Šš‚‹›Šš€‰™€‰˜ˆ—{„“{„“zƒ’xu~s|‹pyˆox‡ox‡irhr~gq}emyfnzdlw`hs]ep[cnZ`kV\gSZcPW`MR\LQ[IOVFLSAGN?EL04:.28.28,06,06+/5+/5+/5+/5*.4+/5+/5+/5+/5+/5*.4+/5+/5+/5*.4)-3'+1&*0%)/#(+"'*#&)"%(#&)$'*$'*&),'*-*-0(+.),/),/(+.*-0*-0*-0(+.),/),/'*-'*-%*-%*-$),$),$),&+.%*-$),$),%*-&),'*-',/+03+03+03/2547:7:=7:=7:=8;>8;>69<69<58;368146/24-02-02+.0./1  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + pu€pu€pu€qvqvqu‚rvƒrw‚qvsxƒty„qvqvrw‚rw‚qvqvrw‚sxƒsw„tx…ty„sxƒty„ty„uz…v{†vz‡w{ˆuy†vz‡vz‡vz‡w{ˆw{ˆx|‰y}Šx|‰x|‰x|‰z~‹z~‹{Œy}Šz~‹|€|€|€}Ž}Ž}Ž}‚~ƒ~ƒ~ƒ~ƒ’„“„“„“€…”„“€…”†•†•‚‡–‚‡–†•„‰˜…Š™†‹š…Š™…Š™…Š™„‰˜…Š™„‰˜„‰˜„‰˜…Š™†‹š†‹š‡Œ›†‹šˆœˆœ‡Œ›ˆœˆš‰Ž›‰Ž›ˆš‡›†Žš…Œ›„‹š†œ…Œ›ƒŠ™„‹š„‹š„‹šƒŠ™„‹š…Œ›…Œ›„‹š„‹š‚‹›‚‹›ŠšŠšŠšŠšŠš€‰™Šš€‰™ˆ—Š™Š™€‰˜‚‹š‚‹šŠ™Š™Š™~‡–|…”|…”wwu}‰s{‡rz…pxƒow‚mu€ou€kq|gnwfmvfkudis`fm\biY_fX^eU\aT[`SW]NRXMQWJNTCGMAEK>BH;?E8/6;.28.28,06+/5*.4*.4)-3(,2(,2(,2'+1'+1&*0&*0$(.$(.$(.%)/$(.$(.$(.%)/%*-$),#(+$),%*-$),#(+$),(-0).1+03+03,14,14/25/25147147258258369369258/25-02*-/-.0   ((&((& '''  + + + + + + + + + + + sxƒsxƒuz…ty„ty„sxƒuz…ty„ty„uz…uz…xz†{}‰y{‡xz†x}ˆy~‰x}ˆx}ˆzŠ{€‹{€‹|Œ|Œ|Œ}‚~ƒŽ}‚}‚}‚~ƒŽ„}‚}Ž~‚}Ž~‚~‚~‚~‚ƒ~‚~‚ƒƒƒƒ€„‘ƒ€„‘€„‘~‚~‚~‚ƒƒƒ€„‘ƒƒƒ€„‘…’…’…’…’…’‚…•‚…•‚…•„‡—…ˆ˜ƒ†–ƒ†–„‡—„‡—„‡—„‡—…ˆ˜ƒˆ—„‰˜…Š™„‰˜ƒˆ—…Š™…Š™ƒˆ—„‰˜„‰˜…Š™„‰˜ƒˆ—„‰˜ƒŠ™„‹š„‹š„‹šƒŠ™ƒŠ™„‹š„‹š„Š›…‹œ„Š›…‹œ„Š›„Š›‚‹›‚‹›ƒŒœŠš‚‹›Šš€‰™€‰™€‰™ˆ˜ˆ˜€‰™ˆ˜ˆ˜ˆ˜}†–~‡—}†–|‡—|‡—|‡—|‡—{†–}ˆ˜}ˆ˜}ˆ˜~‰™~‰™{‡—}‰™|ˆ˜}‰™}‰™|ˆ˜|ˆ˜}‰™}‰™}‰™}‰™}‰™}‰™}‰™~Šš~Šš~‹™Œš€›€›€›~‹™~Š˜‹™{‡•}‰—wƒv‚Žwu‹q|†p{…oz„nyƒow‚iq|kr{fmvdktahq]dkX_fW]dRX_PW\MTYMQWIMSGKQDHN?CI;?E:>D6:@26<15;.28,06)-3(,2&*0&*0&*0&*0%)/$(.&*0%)/$),#(+"'*"'*$),#(+"'*#(+%*-).1+03+03+03,14/25-03/25036036147258147258036.13+.0-.0      !!''% )))       + v{…v{…w|†w|†v{…w|†x}‡x{…wz„wz„x{…z|ˆy{‡z|ˆz|ˆ{}‰{}‰|~Š}‹~€Œ€‚Ž€‚Ž€‚Žƒƒƒ€‚Ž€‚Žƒƒ€‚Ž€‚Ž€…€…€…†‘€…€……’…’…’‚†“€„‘ƒ‡”‚†“€„‘ƒ€„‘ƒ…’…’€„‘‚†“…’‚†“‚†“‚†“…’…’…’…’…’…’‚†“‚†“ƒ‡”‚…•„‡—ƒ†–ƒ†–„‡—„‡—…ˆ˜ƒ†–ƒˆ—ƒˆ—„‰˜ƒˆ—ƒˆ—„‰˜„‰˜ƒˆ—ƒˆ—ƒˆ—„‰˜„‰˜ƒˆ—ƒˆ—ƒŠ™‚‰˜‚‰˜ƒŠ™ƒŠ™ƒŠ™ƒ‰š‚ˆ™„Š›„Š›ƒ‰š„Š›ƒ‰šƒ‰šƒ‰šƒ‰šŠš€‰™€‰™ˆ˜ˆ˜ˆ˜~‡—ˆ˜ˆ˜~‡—ˆ˜~‡—|…•}†–{†–{†–{†–{†–}ˆ˜|‡—|‡—~‰™~‰™ŠšŠšŠš}‰™}‰™}‰™|ˆ˜}‰™}‰™|ˆ˜~Šš~Šš}‰™}‰™}‰™~Šš}‰™~Šš~Šš‹›}‰™€Œœ€Œœ~Šš‹›€Œœ‚Žž€Œœ‹›€›Œš{ˆ–w„’w„’u‚rp}‹q}‰nz†lx„kwƒjv‚dp|cnxalv_jt[fpZclW`iW^gRYbRYbMT]JOYGLVDJQ>DKD8EJ7>C5:=169036*-0'*,#&(!"$!          +     +  +   + +  +  …ˆ’…ˆ’‡Š”†‰“‡Š”‡Š”†‰“†‰“†‰“‡Š”‡Š”ˆ‹•‡Š”ˆ‹•‰Œ–‰Œ–‰Œ–‰Œ–‡Š”ˆ‹•ˆ‹•‰Œ–ˆ‹•ˆŠ–ˆŠ–‡‰•‡‰•†ˆ”‡‰•ˆŠ–‰‹—ŒŽšŠŒ˜‹™‹™ŠŒ˜ŠŒ˜‹™‹™ŠŒ˜‹™ŒŽš›‹™ŒŽš‹™›ŒŽš››››ŒŽš››œŽ‘žŽŽœ‹œŒŒ‹œ‹œ‹œŒ‹œ‹œŒ‹œŠŽ›ŠŠŠˆ‹›‰Œœˆ‹›ˆ‹›ˆ‹›†‹š†‹š†‹š‡Œ›ˆœˆœˆœ‡Œ›‡Œ›‡Œ›‰Ž‡Œ›†‹š…Š™†‹š…Š™…‰š…‰š…‰š†Š›…‰š†Š›ƒ‰šƒ‰š‚ˆ™ƒ‰š‚ˆ™‡˜‡˜‡˜€†—€†—~‡—ˆ˜€‰™ˆ˜~‡—~‡—ˆ˜~‡—}†–}†–z„—z„—{…˜z„—{…˜}‡š{…˜|†™|†™~ˆ›}‡š~ˆ›}‰›}‰›|ˆš}‰›}‰›|ˆš|ˆš}‰›|ˆš|ˆš|ˆš|ˆš~Šœ}‰›|ˆš}‰›}‰›~Šœ~Šš~Šš‹›~Šš|ˆ˜~Šš~Šš‹›|‹š|‹š}Œ›Ž}Œ›~œ|‹š}Œ›}Œ›~œ~œ~œ|‹š~œ~œ~œŽŽŽ~œŽ~œ|‹š}Œ›~œ}Œ›~œŽŽŽ€ž€ž€ž€ž€žŸ€ž€žŸ€žƒŸƒŸ„ „ ƒŸƒŸƒŸƒŸ„‘Ÿƒž„‘Ÿ„‘Ÿ…’ „‘Ÿƒž‚‚›€Ž™š˜‹—{‡“z‡‘{ˆ’xƒt‰s~ˆq|†qzƒpy‚ipwhovfnsdlqbinZafY^aRWZQTWJMPGKLBFGBCE=>@8::355111///)))&&&!##        +   +   +  +      †Š‘…‰†Š‘‰”‡‹’‡‹’‰”ˆ‹•‰Œ–ˆ‹•Š—‰Œ–Š—Š—‹Ž˜Š—‹Ž˜Š—‰Œ–‰Œ–ˆ‹•ˆ‹•Š—‰Œ–Š—Š—ˆ‹•ˆ‹•ˆ‹•ŠŒ˜ŠŒ˜‹™‹™‹™ŒŽšŒŽš›ŒŽšŒŽšŒŽš‹™ŒŽš‹™ŠŒ˜‹™‹™›››ŒŽš›ŽœŽœ›Žœ›‘‘Žœ‘ŽœŽ‘ž‘žŒ‘ž‘žŒ‘ž‘žŒ‹œŒ‹œŠŽ›ŠŽ›ŠŽ›‰Œœ‰Œœ‰Œœ‡Ššˆ‹›ˆ‹›‡Œ›Šžˆœ‡Œ›‰Žˆœˆœ‡Œ›‡Œ›‡Œ›†‹š†‹š…Š™…Š™…‰š…‰š…‰š…‰š„ˆ™„ˆ™‚ˆ™ƒ‰š‚ˆ™ƒ‰š‚ˆ™‡˜€†—‡˜‡˜‚ˆ™ˆ˜ˆ˜ˆ˜~‡—~‡—~‡—~‡—}†–|…•}†–|†™{…˜yƒ–yƒ–{…˜{…˜z„—|†™|†™}‡š}‡š}‡š}‡š|†™z†˜{‡™z†˜{‡™{‡™{‡™{‡™{‡™{‡™|ˆš|ˆš{‡™{‡™|ˆš|ˆš|ˆš}‰›}‰›~Šš~Šš}‰›~Šœ‹‹‹‹~Šš~Šš~Šœ~Šœ}‰›|ˆš}‰›|ˆš}‰™~Šš{Š™|‹š{Š™~œ~Œž~Œž}‹~Œž~œ|‹š|Šœ}‹}Œ›|‹š}Œ›}Œ›~œ~œ~œ€ž€žŽŽŽŽŽŽŽ‚Žž‚Žž‚Žž‚ŽžƒŸƒŸƒŸ„ „ ƒŸƒŸ‚ŽžŽœŽœ€›ŽœƒŸƒŸƒŸ„ ƒŸŽœ‚Œš€›{Š˜x‡•uƒŽp~‰o}ˆn|‡lz…jxƒjwgt~gt~dq{_jt]hrZclS\eR\bLV\GNUCJQBIN;BG9=C7;A169+03+.0&)+!$&"$ ""!!               +  ˆŒ“‡‹’‰”ˆŒ“‰”‰”‰”ˆ‹•‰Œ–‹Ž˜‰Œ–Š—‹Ž˜Š—‹Ž˜‹Ž˜‹Ž˜Š—Š—Š—Š—Š—Œ™‹Ž˜‹Ž˜‹Ž˜‹Ž˜‹Ž˜‹Ž˜ŒŽšŒŽšŒŽš›ŒŽšŽœŒŽšŽœŽœ›››ŒŽšŒŽš››ŒŽšŒŽš‘›Žœ’ž‘ŽœŽœ‘’ž’ž’ž’ž‘‘‘ž’Ÿ‘ž‘žŒŒŽ’ŸŽ’ŸŽ’ŸŽ’Ÿ‘ž‘ž‹œ‹œŒ‹œŠŒŸŠŠ‰Œœˆ‹›ˆœ‰Ž‰Žˆœ‰ŽŠžˆœ‰Žˆœ‰Ž‡Œ›‡Œ›†‹š†‹šˆŒ†Š›„ˆ™†Š›…‰š…‰š‚ˆ™ƒ‰š‚ˆ™‡˜‡˜€†—‡˜‡˜‚ˆ™‡˜~‡—ˆ˜€‰™}†–~‡—}†–~‡—|…•|…•}†–}‡šyƒ–yƒ–yƒ–yƒ–z„—{…˜{…˜{…˜{…˜|†™|†™{…˜{…˜y…—z†˜z†˜{‡™{‡™{‡™{‡™{‡™{‡™z†˜{‡™{‡™{‡™{‡™|ˆš|ˆš|ˆš}‰›}‰™}‰™}‰›}‰›~Šœ~Šœ~Šœ‹~Šš~Šš}‰›}‰›|ˆš|ˆš}‰›{‡™{‡—{‡—z‰˜z‰˜z‰˜}Œ›}‹}‹}‹}‹|‹š~œ|Šœ|Šœ}Œ›~œ}Œ›}Œ›~œ~œ~œ}Œ›~œŽ~œ}Œ›ŽŽ~œ~œ‚Žž‚Žž‚Žž‚Žž‚ŽžƒŸƒŸ„ „ „ „ ƒŸ‚ŽžŽœŽœ€›Žœ€Œœ‚ŽžƒŸ‚Žž‚Žžƒž‚‚„‘Ÿ€€„’„’ƒ‘œ‚›~Œ—|Š•z‡‘vƒt‹t‹r}‡q|†u~‡py‚mw}isygnucjqcjo\chZ^dUY_QVYKPSHLMEIJAEFEJ=BE7@;>@9<>235013688/11'))%''!##         + Ž–Ž—Ž—˜˜Ž—˜˜Ž—Ž™Ž™Ž™šššŽ™šŽ™Ž™‘›šš‘›‘›š‘’œ‘›š‘›‘›‘›‘›‘’œ’œ’œ’žŽœŽœ‘’žŽœ‘‘‘‘‘‘“Ÿ‘“Ÿ’ž’ž‘“Ÿ‘“Ÿ‘“Ÿ‘“Ÿ’ž‘“Ÿ’ž• ”ŸŽ“žŽ“ž”Ÿ”Ÿ”¡“ “ “ “ ”¡”¡“ ‘•¢“ “ Ž’Ÿ“ Ž’ŸŽ’ŸŽ’ŸŽ’ŸŒ‘žŒŒ‹œ‹ŸŠž‰Ž‰Ž‰ŽŠžŠžŠžŠž‰Žˆœ‰ŽˆŒˆŒ‡‹œ†Š›†Š›†Š›ƒ‰šƒ‰š‚ˆ™‚ˆ™‡˜‡˜‡˜…–‡˜€†—…–…–}†–}†–|…•|…•{„”zƒ“zƒ“zƒ“{„”zƒ“zƒ“{„”x‚•yƒ–x‚•yƒ–w”x‚•yƒ–yƒ–z„—yƒ–z„—yƒ–{…˜z„—{…˜z„—yƒ–{…˜y…—y…—y…—y…—x„–y…—y…—z†˜y…—{‡™z†˜{‡™{‡™{‡™{‡™{‡™{‡™z†˜|ˆš{‡™{‡™z†˜y…—y…—z†˜z†˜{‡™z†˜z†˜{‡™y‡™y‡™{‰›|Šœ|Šœ|Šœ}‹}‹~Œž}‹~Œž~Œž|Šœ|Šœ}‹~Œž}‹}‹}Œ›Ž~œ~œŽŽ‚Žž‚Žž‚Žž‚Žž‚ŽžƒŸ„ ƒŸ„ …‘¡…‘¡…‘¡„ „ ƒŸƒŸ‚‘ ‚‘ ‚‘ ‚‘ €žŽ‚Žž‚Žž‚Žœ~›~›ž€ƒž‚€Žœ‚ƒž…’ ƒžƒž„‘Ÿƒž„‘Ÿ„‘Ÿ„‘Ÿ„‘Ÿ…’ „‘Ÿ„‘Ÿ…’ „‘Ÿ‚›ƒ‘œ‚›‚›€Ž™˜|Š”zˆ’t‚Œt‚Œq~ˆo|†o|†jwgu}bpxcnw^ir\enV_hR\bOY_MT[MT[GOTDLQDKPCJO>EH=DG;@C7 + + + diff --git a/bindings/js/example/run.sh b/bindings/js/example/run.sh new file mode 100755 index 000000000..79a6cde7a --- /dev/null +++ b/bindings/js/example/run.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e +cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 + +# This has to exist, if it doesn't please run ./bindings/js/configure.sh && ./bindings/js/build.sh first +cp ../../../build/bindings/js/depthai-js.wasm public/ +./build.sh +cd public +echo Example is running... +echo Please navigate to http://localhost:8000/ in a browser and check the javascript console output. +echo Then modify index.html to suit your needs. +python3 -m http.server + diff --git a/bindings/js/example/serialize.cpp b/bindings/js/example/serialize.cpp new file mode 100644 index 000000000..d876ebc35 --- /dev/null +++ b/bindings/js/example/serialize.cpp @@ -0,0 +1,59 @@ +#include + +// include depthai library +#include +#include + +// include opencv library (Optional, used only for the following example) +#include + +using namespace std; + +template +void writeMessageToFile(const T& message, const char* filename) { + const auto metadata = dai::StreamMessageParser::serializeMetadata(message); + const auto data = message->getData(); + ofstream myfile; + myfile.open(filename, ios::out | ios::binary); + myfile.write(reinterpret_cast(data.data()), data.size() * sizeof(data.front())); + myfile.write(reinterpret_cast(metadata.data()), metadata.size() * sizeof(metadata.front())); + myfile.close(); +} + +int main() { + // Create pipeline + dai::Pipeline pipeline; + auto colorCam = pipeline.create(); + auto xlinkOut = pipeline.create(); + xlinkOut->setStreamName("preview"); + colorCam->setInterleaved(true); + colorCam->preview.link(xlinkOut->input); + + try { + // Try connecting to device and start the pipeline + dai::Device device(pipeline); + + // Get output queue + auto preview = device.getOutputQueue("preview"); + + cv::Mat frame; + while(true) { + // Receive 'preview' frame from device + auto imgFrame = preview->get(); + std::vector data; + writeMessageToFile(imgFrame, "img_frame.dump"); + + // Show the received 'preview' frame + cv::imshow("preview", cv::Mat(imgFrame->getHeight(), imgFrame->getWidth(), CV_8UC3, imgFrame->getData().data())); + + // Wait and check if 'q' pressed + if(cv::waitKey(1) == 'q') return 0; + } + } catch(const std::runtime_error& err) { + std::cout << err.what() << std::endl; + return 1; + } + + return 0; +} + diff --git a/bindings/js/example/src/index.ts b/bindings/js/example/src/index.ts new file mode 100644 index 000000000..8edd432b1 --- /dev/null +++ b/bindings/js/example/src/index.ts @@ -0,0 +1,34 @@ +import depthaiInitialize, { parseMessage, arrayToVector } from "depthai-js"; + +(async () => { + const dai = await depthaiInitialize(); + console.log(Object.keys(dai)); + const req = new XMLHttpRequest(); + req.open("GET", "/img_frame.dump", true); + req.responseType = "arraybuffer"; + req.onload = () => { + const arrayBuffer = req.response; + if (arrayBuffer) { + const message = parseMessage(arrayBuffer); + console.log(message); + const msgType = message.type; + const vectorMetadata = arrayToVector(message.metadata); + let res; + if (msgType === dai.DatatypeEnum.ImgFrame) { + console.log("message type is ImgFrame"); + res = dai.deserializeImgFrame(vectorMetadata); + console.log("deserializeImgFrame result: ", res); + console.log("DIMS from javascript: ", res.width, "x", res.height); + } else if (msgType === dai.DatatypeEnum.ImgDetections) { + console.log("message type is ImgDetections"); + res = dai.deserializeImgDetections(vectorMetadata); + } else { + throw Error("Unhandled message type: " + msgType); + } + console.log(res); + } else { + console.error("Not an array buffer"); + } + }; + req.send(null); +})(); diff --git a/bindings/js/example/tsconfig.json b/bindings/js/example/tsconfig.json new file mode 100644 index 000000000..7ae453dc3 --- /dev/null +++ b/bindings/js/example/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "outDir": "public/dist", + "target": "es6", + "module": "esnext", + "moduleResolution": "bundler", + "lib": [ + "es2015", + "dom" + ], + "sourceMap": true, + "strict": true, + "strictFunctionTypes": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "noImplicitAny": true, + "strictNullChecks": true, + "alwaysStrict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "declaration": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true + }, + "include": ["src"], + "exclude": ["node_modules", "public", "**/*.test.ts"] +} diff --git a/bindings/js/package-lock.json b/bindings/js/package-lock.json new file mode 100644 index 000000000..8182bb88f --- /dev/null +++ b/bindings/js/package-lock.json @@ -0,0 +1,8162 @@ +{ + "name": "depthai-js", + "version": "0.0.1", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "depthai-js", + "version": "0.0.1", + "license": "MIT", + "devDependencies": { + "@babel/cli": "^7.23.9", + "@babel/core": "^7.24.0", + "@babel/preset-env": "^7.24.0", + "@babel/preset-typescript": "^7.23.3", + "@rollup/plugin-babel": "^6.0.4", + "@rollup/plugin-node-resolve": "^15.2.3", + "cross-env": "^7.0.3", + "npm-run-all": "^4.1.5", + "rimraf": "^5.0.5", + "rollup": "^2.79.1", + "rollup-plugin-terser": "^7.0.2", + "typescript": "^5.3.3" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/cli": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.23.9.tgz", + "integrity": "sha512-vB1UXmGDNEhcf1jNAHKT9IlYk1R+hehVTLFlCLHBi8gfuHQGP6uRjgXVYU0EVlI/qwAWpstqkBdf2aez3/z/5Q==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.17", + "commander": "^4.0.1", + "convert-source-map": "^2.0.0", + "fs-readdir-recursive": "^1.1.0", + "glob": "^7.2.0", + "make-dir": "^2.1.0", + "slash": "^2.0.0" + }, + "bin": { + "babel": "bin/babel.js", + "babel-external-helpers": "bin/babel-external-helpers.js" + }, + "engines": { + "node": ">=6.9.0" + }, + "optionalDependencies": { + "@nicolo-ribaudo/chokidar-2": "2.1.8-no-fsevents.3", + "chokidar": "^3.4.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.0.tgz", + "integrity": "sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.24.0", + "@babel/parser": "^7.24.0", + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.0", + "@babel/types": "^7.24.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.23.6", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", + "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.0.tgz", + "integrity": "sha512-QAH+vfvts51BCsNZ2PhY6HAggnlS6omLLFTsIpeqZk/MmJ6cW7tgz5yRv0fMJThcr6FmbMrENh1RgrWPTYA76g==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-member-expression-to-functions": "^7.23.0", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", + "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.5.0.tgz", + "integrity": "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", + "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", + "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz", + "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", + "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-wrap-function": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", + "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-optimise-call-expression": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", + "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", + "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", + "dev": true, + "dependencies": { + "@babel/helper-function-name": "^7.22.5", + "@babel/template": "^7.22.15", + "@babel/types": "^7.22.19" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.0.tgz", + "integrity": "sha512-ulDZdc0Aj5uLc5nETsa7EPx2L7rM0YJM8r7ck7U73AXi7qOV44IHHRAYZHY6iU1rr3C5N4NtTmMRUJP6kwCWeA==", + "dev": true, + "dependencies": { + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.0", + "@babel/types": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz", + "integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz", + "integrity": "sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz", + "integrity": "sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-transform-optional-chaining": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.7.tgz", + "integrity": "sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz", + "integrity": "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz", + "integrity": "sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", + "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", + "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz", + "integrity": "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.9.tgz", + "integrity": "sha512-8Q3veQEDGe14dTYuwagbRtwxQDnytyg1JFu4/HwEMETeofocrB0U0ejBJIXoeG/t2oXZ8kzCyI0ZZfbT80VFNQ==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.20", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz", + "integrity": "sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz", + "integrity": "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz", + "integrity": "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz", + "integrity": "sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz", + "integrity": "sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.23.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.8.tgz", + "integrity": "sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-split-export-declaration": "^7.22.6", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz", + "integrity": "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/template": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz", + "integrity": "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz", + "integrity": "sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz", + "integrity": "sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz", + "integrity": "sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz", + "integrity": "sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==", + "dev": true, + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz", + "integrity": "sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.6.tgz", + "integrity": "sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz", + "integrity": "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz", + "integrity": "sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz", + "integrity": "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz", + "integrity": "sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz", + "integrity": "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz", + "integrity": "sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz", + "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.9.tgz", + "integrity": "sha512-KDlPRM6sLo4o1FkiSlXoAa8edLXFsKKIda779fbLrvmeuc3itnjCtaO6RrtoaANsIJANj+Vk1zqbZIMhkCAHVw==", + "dev": true, + "dependencies": { + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz", + "integrity": "sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", + "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz", + "integrity": "sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz", + "integrity": "sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz", + "integrity": "sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.0.tgz", + "integrity": "sha512-y/yKMm7buHpFFXfxVFS4Vk1ToRJDilIa6fKRioB9Vjichv58TDGXTvqV0dN7plobAmTW5eSEGXDngE+Mm+uO+w==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz", + "integrity": "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz", + "integrity": "sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz", + "integrity": "sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz", + "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz", + "integrity": "sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz", + "integrity": "sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz", + "integrity": "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz", + "integrity": "sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz", + "integrity": "sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz", + "integrity": "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz", + "integrity": "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz", + "integrity": "sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz", + "integrity": "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz", + "integrity": "sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.6.tgz", + "integrity": "sha512-6cBG5mBvUu4VUD04OHKnYzbuHNP8huDsD3EDqqpIpsswTDoqHCjLoHb6+QgsV1WsT2nipRqCPgxD3LXnEO7XfA==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.23.6", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-typescript": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz", + "integrity": "sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz", + "integrity": "sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz", + "integrity": "sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz", + "integrity": "sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.0.tgz", + "integrity": "sha512-ZxPEzV9IgvGn73iK0E6VB9/95Nd7aMFpbE0l8KQFDG70cOV9IxRP7Y2FUPmlK0v6ImlLqYX50iuZ3ZTVhOF2lA==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-validator-option": "^7.23.5", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.7", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.23.3", + "@babel/plugin-syntax-import-attributes": "^7.23.3", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.23.3", + "@babel/plugin-transform-async-generator-functions": "^7.23.9", + "@babel/plugin-transform-async-to-generator": "^7.23.3", + "@babel/plugin-transform-block-scoped-functions": "^7.23.3", + "@babel/plugin-transform-block-scoping": "^7.23.4", + "@babel/plugin-transform-class-properties": "^7.23.3", + "@babel/plugin-transform-class-static-block": "^7.23.4", + "@babel/plugin-transform-classes": "^7.23.8", + "@babel/plugin-transform-computed-properties": "^7.23.3", + "@babel/plugin-transform-destructuring": "^7.23.3", + "@babel/plugin-transform-dotall-regex": "^7.23.3", + "@babel/plugin-transform-duplicate-keys": "^7.23.3", + "@babel/plugin-transform-dynamic-import": "^7.23.4", + "@babel/plugin-transform-exponentiation-operator": "^7.23.3", + "@babel/plugin-transform-export-namespace-from": "^7.23.4", + "@babel/plugin-transform-for-of": "^7.23.6", + "@babel/plugin-transform-function-name": "^7.23.3", + "@babel/plugin-transform-json-strings": "^7.23.4", + "@babel/plugin-transform-literals": "^7.23.3", + "@babel/plugin-transform-logical-assignment-operators": "^7.23.4", + "@babel/plugin-transform-member-expression-literals": "^7.23.3", + "@babel/plugin-transform-modules-amd": "^7.23.3", + "@babel/plugin-transform-modules-commonjs": "^7.23.3", + "@babel/plugin-transform-modules-systemjs": "^7.23.9", + "@babel/plugin-transform-modules-umd": "^7.23.3", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", + "@babel/plugin-transform-new-target": "^7.23.3", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.4", + "@babel/plugin-transform-numeric-separator": "^7.23.4", + "@babel/plugin-transform-object-rest-spread": "^7.24.0", + "@babel/plugin-transform-object-super": "^7.23.3", + "@babel/plugin-transform-optional-catch-binding": "^7.23.4", + "@babel/plugin-transform-optional-chaining": "^7.23.4", + "@babel/plugin-transform-parameters": "^7.23.3", + "@babel/plugin-transform-private-methods": "^7.23.3", + "@babel/plugin-transform-private-property-in-object": "^7.23.4", + "@babel/plugin-transform-property-literals": "^7.23.3", + "@babel/plugin-transform-regenerator": "^7.23.3", + "@babel/plugin-transform-reserved-words": "^7.23.3", + "@babel/plugin-transform-shorthand-properties": "^7.23.3", + "@babel/plugin-transform-spread": "^7.23.3", + "@babel/plugin-transform-sticky-regex": "^7.23.3", + "@babel/plugin-transform-template-literals": "^7.23.3", + "@babel/plugin-transform-typeof-symbol": "^7.23.3", + "@babel/plugin-transform-unicode-escapes": "^7.23.3", + "@babel/plugin-transform-unicode-property-regex": "^7.23.3", + "@babel/plugin-transform-unicode-regex": "^7.23.3", + "@babel/plugin-transform-unicode-sets-regex": "^7.23.3", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.8", + "babel-plugin-polyfill-corejs3": "^0.9.0", + "babel-plugin-polyfill-regenerator": "^0.5.5", + "core-js-compat": "^3.31.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.23.3.tgz", + "integrity": "sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-syntax-jsx": "^7.23.3", + "@babel/plugin-transform-modules-commonjs": "^7.23.3", + "@babel/plugin-transform-typescript": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", + "dev": true + }, + "node_modules/@babel/runtime": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.0.tgz", + "integrity": "sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", + "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/parser": "^7.24.0", + "@babel/types": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.0.tgz", + "integrity": "sha512-HfuJlI8qq3dEDmNU5ChzzpZRWq+oxCZQyMzIMEqLho+AQnhMnKQUzH6ydo3RBl/YjPCuk68Y6s0Gx0AeyULiWw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.24.0", + "@babel/types": "^7.24.0", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", + "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.4.tgz", + "integrity": "sha512-Oud2QPM5dHviZNn4y/WhhYKSXksv+1xLEIsNrAbGcFzUN3ubqWRFT5gwPchNc5NuzILOU4tPBDTZ4VwhL8Y7cw==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.23.tgz", + "integrity": "sha512-9/4foRoUKp8s96tSkh8DlAAc5A0Ty8vLXld+l9gjKKY6ckwI8G15f0hskGmuLZu78ZlGa1vtsfOa+lnB4vG6Jg==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nicolo-ribaudo/chokidar-2": { + "version": "2.1.8-no-fsevents.3", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz", + "integrity": "sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==", + "dev": true, + "optional": true + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@rollup/plugin-babel": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-6.0.4.tgz", + "integrity": "sha512-YF7Y52kFdFT/xVSuVdjkV5ZdX/3YtmX0QulG+x0taQOtJdHYzVU61aSSkAgVJ7NOv6qPkIYiJSgSWWN/DM5sGw==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.18.6", + "@rollup/pluginutils": "^5.0.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "@types/babel__core": "^7.1.9", + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "@types/babel__core": { + "optional": true + }, + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "15.2.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", + "integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-builtin-module": "^3.2.1", + "is-module": "^1.0.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.78.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", + "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.11.22", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.22.tgz", + "integrity": "sha512-/G+IxWxma6V3E+pqK1tSl2Fo1kl41pK1yeCyDsgkF9WlVAme4j5ISYM2zR11bgLFJGLN5sVK40T4RJNuiZbEjA==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/resolve": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "optional": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.8.tgz", + "integrity": "sha512-OtIuQfafSzpo/LhnJaykc0R/MMnuLSSVjVYy9mHArIZ9qTCSZ6TpWCuEKZYVoN//t8HqBNScHrOtCrIK5IaGLg==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.5.0", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.9.0.tgz", + "integrity": "sha512-7nZPG1uzK2Ymhy/NbaOWTg3uibM2BmGASS4vHS4szRZAIR8R6GwA/xAujpdrXU5iyklrimWnLWU+BLF9suPTqg==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.5.0", + "core-js-compat": "^3.34.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.5.tgz", + "integrity": "sha512-OJGYZlhLqBh2DDHeqAxWB1XIvr49CxiJ2gIt61/PU55CQK4Z58OzMqjDe1zwQdQk+rBYsRc+1rJmdajM3gimHg==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.5.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "optional": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001591", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001591.tgz", + "integrity": "sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "optional": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/core-js-compat": { + "version": "3.36.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.0.tgz", + "integrity": "sha512-iV9Pd/PsgjNWBXeq8XRtWVSgz2tKAfhfvBs7qxYty+RlRd+OCksaWmOnc4JKrTc1cToXL1N0s3l/vwlxPtdElw==", + "dev": true, + "dependencies": { + "browserslist": "^4.22.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/electron-to-chromium": { + "version": "1.4.687", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.687.tgz", + "integrity": "sha512-Ic85cOuXSP6h7KM0AIJ2hpJ98Bo4hyTUjc4yjMbkvD+8yTxEhfK9+8exT2KKYsSjnCn2tGsKVSZwE7ZgTORQCw==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.22.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.5.tgz", + "integrity": "sha512-oW69R+4q2wG+Hc3KZePPZxOiisRIqfKBVo/HLx94QcJeWGU/8sZhCvc829rd1kS366vlJbzBfXf9yWwf0+Ko7w==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.1", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.0", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.8", + "string.prototype.trimend": "^1.0.7", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.5", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "optional": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "optional": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", + "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "optional": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "dependencies": { + "builtin-modules": "^3.3.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "optional": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "dev": true + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-all": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", + "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "memorystream": "^0.3.1", + "minimatch": "^3.0.4", + "pidtree": "^0.3.0", + "read-pkg": "^3.0.0", + "shell-quote": "^1.6.1", + "string.prototype.padend": "^3.0.0" + }, + "bin": { + "npm-run-all": "bin/npm-run-all/index.js", + "run-p": "bin/run-p/index.js", + "run-s": "bin/run-s/index.js" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/npm-run-all/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/npm-run-all/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-all/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/npm-run-all/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-all/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-all/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dev": true, + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", + "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-type/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pidtree": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", + "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", + "dev": true, + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "dev": true, + "dependencies": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "optional": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true + }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "dev": true, + "dependencies": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "dev": true, + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/rimraf": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", + "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", + "dev": true, + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup-plugin-terser": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", + "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", + "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "jest-worker": "^26.2.1", + "serialize-javascript": "^4.0.0", + "terser": "^5.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.0.tgz", + "integrity": "sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "get-intrinsic": "^1.2.2", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", + "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.2", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz", + "integrity": "sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz", + "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==", + "dev": true + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.padend": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.5.tgz", + "integrity": "sha512-DOB27b/2UTTD+4myKUFh+/fXWcu/UDyASIXfg+7VzoCNNGOfWvoyU/x5pvVHr++ztyt/oSYI1BcWBBG/hmlNjA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", + "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", + "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", + "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/terser": { + "version": "5.28.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.28.1.tgz", + "integrity": "sha512-wM+bZp54v/E9eRRGXb5ZFDvinrJIOaTapx3WUokyVGZu5ucVCK55zEgGd5Dl2fSr3jUo5sDiERErUWLY6QPFyA==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "optional": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.5.tgz", + "integrity": "sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.14.tgz", + "integrity": "sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.6", + "call-bind": "^1.0.5", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + } + }, + "dependencies": { + "@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@babel/cli": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.23.9.tgz", + "integrity": "sha512-vB1UXmGDNEhcf1jNAHKT9IlYk1R+hehVTLFlCLHBi8gfuHQGP6uRjgXVYU0EVlI/qwAWpstqkBdf2aez3/z/5Q==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.17", + "@nicolo-ribaudo/chokidar-2": "2.1.8-no-fsevents.3", + "chokidar": "^3.4.0", + "commander": "^4.0.1", + "convert-source-map": "^2.0.0", + "fs-readdir-recursive": "^1.1.0", + "glob": "^7.2.0", + "make-dir": "^2.1.0", + "slash": "^2.0.0" + } + }, + "@babel/code-frame": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "dev": true, + "requires": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + } + }, + "@babel/compat-data": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "dev": true + }, + "@babel/core": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.0.tgz", + "integrity": "sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw==", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.24.0", + "@babel/parser": "^7.24.0", + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.0", + "@babel/types": "^7.24.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + } + }, + "@babel/generator": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "dev": true, + "requires": { + "@babel/types": "^7.23.6", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", + "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", + "dev": true, + "requires": { + "@babel/types": "^7.22.15" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.0.tgz", + "integrity": "sha512-QAH+vfvts51BCsNZ2PhY6HAggnlS6omLLFTsIpeqZk/MmJ6cW7tgz5yRv0fMJThcr6FmbMrENh1RgrWPTYA76g==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-member-expression-to-functions": "^7.23.0", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "semver": "^6.3.1" + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", + "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" + } + }, + "@babel/helper-define-polyfill-provider": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.5.0.tgz", + "integrity": "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q==", + "dev": true, + "requires": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + } + }, + "@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "dev": true + }, + "@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dev": true, + "requires": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", + "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", + "dev": true, + "requires": { + "@babel/types": "^7.23.0" + } + }, + "@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "dev": true, + "requires": { + "@babel/types": "^7.22.15" + } + }, + "@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", + "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz", + "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==", + "dev": true + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", + "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-wrap-function": "^7.22.20" + } + }, + "@babel/helper-replace-supers": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", + "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-optimise-call-expression": "^7.22.5" + } + }, + "@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", + "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-string-parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "dev": true + }, + "@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "dev": true + }, + "@babel/helper-wrap-function": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", + "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.22.5", + "@babel/template": "^7.22.15", + "@babel/types": "^7.22.19" + } + }, + "@babel/helpers": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.0.tgz", + "integrity": "sha512-ulDZdc0Aj5uLc5nETsa7EPx2L7rM0YJM8r7ck7U73AXi7qOV44IHHRAYZHY6iU1rr3C5N4NtTmMRUJP6kwCWeA==", + "dev": true, + "requires": { + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.0", + "@babel/types": "^7.24.0" + } + }, + "@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz", + "integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==", + "dev": true + }, + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz", + "integrity": "sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz", + "integrity": "sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-transform-optional-chaining": "^7.23.3" + } + }, + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.7.tgz", + "integrity": "sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "requires": {} + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-syntax-import-assertions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz", + "integrity": "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-syntax-import-attributes": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz", + "integrity": "sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", + "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-typescript": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", + "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz", + "integrity": "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-async-generator-functions": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.9.tgz", + "integrity": "sha512-8Q3veQEDGe14dTYuwagbRtwxQDnytyg1JFu4/HwEMETeofocrB0U0ejBJIXoeG/t2oXZ8kzCyI0ZZfbT80VFNQ==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.20", + "@babel/plugin-syntax-async-generators": "^7.8.4" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz", + "integrity": "sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.20" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz", + "integrity": "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz", + "integrity": "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-class-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz", + "integrity": "sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-class-static-block": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz", + "integrity": "sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.23.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.8.tgz", + "integrity": "sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-split-export-declaration": "^7.22.6", + "globals": "^11.1.0" + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz", + "integrity": "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/template": "^7.22.15" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz", + "integrity": "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz", + "integrity": "sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz", + "integrity": "sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-dynamic-import": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz", + "integrity": "sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz", + "integrity": "sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==", + "dev": true, + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-export-namespace-from": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz", + "integrity": "sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.6.tgz", + "integrity": "sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz", + "integrity": "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==", + "dev": true, + "requires": { + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-json-strings": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz", + "integrity": "sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-json-strings": "^7.8.3" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz", + "integrity": "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-logical-assignment-operators": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz", + "integrity": "sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz", + "integrity": "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz", + "integrity": "sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz", + "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5" + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.9.tgz", + "integrity": "sha512-KDlPRM6sLo4o1FkiSlXoAa8edLXFsKKIda779fbLrvmeuc3itnjCtaO6RrtoaANsIJANj+Vk1zqbZIMhkCAHVw==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20" + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz", + "integrity": "sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", + "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz", + "integrity": "sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz", + "integrity": "sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + } + }, + "@babel/plugin-transform-numeric-separator": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz", + "integrity": "sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + } + }, + "@babel/plugin-transform-object-rest-spread": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.0.tgz", + "integrity": "sha512-y/yKMm7buHpFFXfxVFS4Vk1ToRJDilIa6fKRioB9Vjichv58TDGXTvqV0dN7plobAmTW5eSEGXDngE+Mm+uO+w==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.23.3" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz", + "integrity": "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20" + } + }, + "@babel/plugin-transform-optional-catch-binding": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz", + "integrity": "sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + } + }, + "@babel/plugin-transform-optional-chaining": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz", + "integrity": "sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz", + "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-private-methods": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz", + "integrity": "sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-private-property-in-object": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz", + "integrity": "sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz", + "integrity": "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz", + "integrity": "sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "regenerator-transform": "^0.15.2" + } + }, + "@babel/plugin-transform-reserved-words": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz", + "integrity": "sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz", + "integrity": "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz", + "integrity": "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz", + "integrity": "sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz", + "integrity": "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz", + "integrity": "sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-typescript": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.6.tgz", + "integrity": "sha512-6cBG5mBvUu4VUD04OHKnYzbuHNP8huDsD3EDqqpIpsswTDoqHCjLoHb6+QgsV1WsT2nipRqCPgxD3LXnEO7XfA==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.23.6", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-typescript": "^7.23.3" + } + }, + "@babel/plugin-transform-unicode-escapes": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz", + "integrity": "sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-unicode-property-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz", + "integrity": "sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz", + "integrity": "sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-unicode-sets-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz", + "integrity": "sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/preset-env": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.0.tgz", + "integrity": "sha512-ZxPEzV9IgvGn73iK0E6VB9/95Nd7aMFpbE0l8KQFDG70cOV9IxRP7Y2FUPmlK0v6ImlLqYX50iuZ3ZTVhOF2lA==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-validator-option": "^7.23.5", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.7", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.23.3", + "@babel/plugin-syntax-import-attributes": "^7.23.3", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.23.3", + "@babel/plugin-transform-async-generator-functions": "^7.23.9", + "@babel/plugin-transform-async-to-generator": "^7.23.3", + "@babel/plugin-transform-block-scoped-functions": "^7.23.3", + "@babel/plugin-transform-block-scoping": "^7.23.4", + "@babel/plugin-transform-class-properties": "^7.23.3", + "@babel/plugin-transform-class-static-block": "^7.23.4", + "@babel/plugin-transform-classes": "^7.23.8", + "@babel/plugin-transform-computed-properties": "^7.23.3", + "@babel/plugin-transform-destructuring": "^7.23.3", + "@babel/plugin-transform-dotall-regex": "^7.23.3", + "@babel/plugin-transform-duplicate-keys": "^7.23.3", + "@babel/plugin-transform-dynamic-import": "^7.23.4", + "@babel/plugin-transform-exponentiation-operator": "^7.23.3", + "@babel/plugin-transform-export-namespace-from": "^7.23.4", + "@babel/plugin-transform-for-of": "^7.23.6", + "@babel/plugin-transform-function-name": "^7.23.3", + "@babel/plugin-transform-json-strings": "^7.23.4", + "@babel/plugin-transform-literals": "^7.23.3", + "@babel/plugin-transform-logical-assignment-operators": "^7.23.4", + "@babel/plugin-transform-member-expression-literals": "^7.23.3", + "@babel/plugin-transform-modules-amd": "^7.23.3", + "@babel/plugin-transform-modules-commonjs": "^7.23.3", + "@babel/plugin-transform-modules-systemjs": "^7.23.9", + "@babel/plugin-transform-modules-umd": "^7.23.3", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", + "@babel/plugin-transform-new-target": "^7.23.3", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.4", + "@babel/plugin-transform-numeric-separator": "^7.23.4", + "@babel/plugin-transform-object-rest-spread": "^7.24.0", + "@babel/plugin-transform-object-super": "^7.23.3", + "@babel/plugin-transform-optional-catch-binding": "^7.23.4", + "@babel/plugin-transform-optional-chaining": "^7.23.4", + "@babel/plugin-transform-parameters": "^7.23.3", + "@babel/plugin-transform-private-methods": "^7.23.3", + "@babel/plugin-transform-private-property-in-object": "^7.23.4", + "@babel/plugin-transform-property-literals": "^7.23.3", + "@babel/plugin-transform-regenerator": "^7.23.3", + "@babel/plugin-transform-reserved-words": "^7.23.3", + "@babel/plugin-transform-shorthand-properties": "^7.23.3", + "@babel/plugin-transform-spread": "^7.23.3", + "@babel/plugin-transform-sticky-regex": "^7.23.3", + "@babel/plugin-transform-template-literals": "^7.23.3", + "@babel/plugin-transform-typeof-symbol": "^7.23.3", + "@babel/plugin-transform-unicode-escapes": "^7.23.3", + "@babel/plugin-transform-unicode-property-regex": "^7.23.3", + "@babel/plugin-transform-unicode-regex": "^7.23.3", + "@babel/plugin-transform-unicode-sets-regex": "^7.23.3", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.8", + "babel-plugin-polyfill-corejs3": "^0.9.0", + "babel-plugin-polyfill-regenerator": "^0.5.5", + "core-js-compat": "^3.31.0", + "semver": "^6.3.1" + } + }, + "@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + } + }, + "@babel/preset-typescript": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.23.3.tgz", + "integrity": "sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-syntax-jsx": "^7.23.3", + "@babel/plugin-transform-modules-commonjs": "^7.23.3", + "@babel/plugin-transform-typescript": "^7.23.3" + } + }, + "@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", + "dev": true + }, + "@babel/runtime": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.0.tgz", + "integrity": "sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.14.0" + } + }, + "@babel/template": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", + "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.23.5", + "@babel/parser": "^7.24.0", + "@babel/types": "^7.24.0" + } + }, + "@babel/traverse": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.0.tgz", + "integrity": "sha512-HfuJlI8qq3dEDmNU5ChzzpZRWq+oxCZQyMzIMEqLho+AQnhMnKQUzH6ydo3RBl/YjPCuk68Y6s0Gx0AeyULiWw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.24.0", + "@babel/types": "^7.24.0", + "debug": "^4.3.1", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", + "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", + "dev": true, + "requires": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + } + }, + "@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "requires": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + } + }, + "@jridgewell/gen-mapping": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.4.tgz", + "integrity": "sha512-Oud2QPM5dHviZNn4y/WhhYKSXksv+1xLEIsNrAbGcFzUN3ubqWRFT5gwPchNc5NuzILOU4tPBDTZ4VwhL8Y7cw==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true + }, + "@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true + }, + "@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.23.tgz", + "integrity": "sha512-9/4foRoUKp8s96tSkh8DlAAc5A0Ty8vLXld+l9gjKKY6ckwI8G15f0hskGmuLZu78ZlGa1vtsfOa+lnB4vG6Jg==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "@nicolo-ribaudo/chokidar-2": { + "version": "2.1.8-no-fsevents.3", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz", + "integrity": "sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==", + "dev": true, + "optional": true + }, + "@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true + }, + "@rollup/plugin-babel": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-6.0.4.tgz", + "integrity": "sha512-YF7Y52kFdFT/xVSuVdjkV5ZdX/3YtmX0QulG+x0taQOtJdHYzVU61aSSkAgVJ7NOv6qPkIYiJSgSWWN/DM5sGw==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.18.6", + "@rollup/pluginutils": "^5.0.1" + } + }, + "@rollup/plugin-node-resolve": { + "version": "15.2.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", + "integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-builtin-module": "^3.2.1", + "is-module": "^1.0.0", + "resolve": "^1.22.1" + } + }, + "@rollup/pluginutils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", + "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", + "dev": true, + "requires": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + } + }, + "@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "@types/node": { + "version": "20.11.22", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.22.tgz", + "integrity": "sha512-/G+IxWxma6V3E+pqK1tSl2Fo1kl41pK1yeCyDsgkF9WlVAme4j5ISYM2zR11bgLFJGLN5sVK40T4RJNuiZbEjA==", + "dev": true, + "requires": { + "undici-types": "~5.26.4" + } + }, + "@types/resolve": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "dev": true + }, + "acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "dev": true + }, + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "optional": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, + "requires": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + } + }, + "arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, + "requires": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + } + }, + "available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "requires": { + "possible-typed-array-names": "^1.0.0" + } + }, + "babel-plugin-polyfill-corejs2": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.8.tgz", + "integrity": "sha512-OtIuQfafSzpo/LhnJaykc0R/MMnuLSSVjVYy9mHArIZ9qTCSZ6TpWCuEKZYVoN//t8HqBNScHrOtCrIK5IaGLg==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.5.0", + "semver": "^6.3.1" + } + }, + "babel-plugin-polyfill-corejs3": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.9.0.tgz", + "integrity": "sha512-7nZPG1uzK2Ymhy/NbaOWTg3uibM2BmGASS4vHS4szRZAIR8R6GwA/xAujpdrXU5iyklrimWnLWU+BLF9suPTqg==", + "dev": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.5.0", + "core-js-compat": "^3.34.0" + } + }, + "babel-plugin-polyfill-regenerator": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.5.tgz", + "integrity": "sha512-OJGYZlhLqBh2DDHeqAxWB1XIvr49CxiJ2gIt61/PU55CQK4Z58OzMqjDe1zwQdQk+rBYsRc+1rJmdajM3gimHg==", + "dev": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.5.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "optional": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browserslist": { + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true + }, + "call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + } + }, + "caniuse-lite": { + "version": "1.0.30001591", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001591.tgz", + "integrity": "sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "optional": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "core-js-compat": { + "version": "3.36.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.0.tgz", + "integrity": "sha512-iV9Pd/PsgjNWBXeq8XRtWVSgz2tKAfhfvBs7qxYty+RlRd+OCksaWmOnc4JKrTc1cToXL1N0s3l/vwlxPtdElw==", + "dev": true, + "requires": { + "browserslist": "^4.22.3" + } + }, + "cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.1" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true + }, + "define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + } + }, + "define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "requires": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + } + }, + "eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "electron-to-chromium": { + "version": "1.4.687", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.687.tgz", + "integrity": "sha512-Ic85cOuXSP6h7KM0AIJ2hpJ98Bo4hyTUjc4yjMbkvD+8yTxEhfK9+8exT2KKYsSjnCn2tGsKVSZwE7ZgTORQCw==", + "dev": true + }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.22.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.5.tgz", + "integrity": "sha512-oW69R+4q2wG+Hc3KZePPZxOiisRIqfKBVo/HLx94QcJeWGU/8sZhCvc829rd1kS366vlJbzBfXf9yWwf0+Ko7w==", + "dev": true, + "requires": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.1", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.0", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.8", + "string.prototype.trimend": "^1.0.7", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.5", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.14" + } + }, + "es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.2.4" + } + }, + "es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true + }, + "es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "optional": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "requires": { + "is-callable": "^1.1.3" + } + }, + "foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + } + }, + "fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true + }, + "function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + } + }, + "functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, + "get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + }, + "get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dev": true, + "requires": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "optional": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3" + } + }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3" + } + }, + "graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "requires": { + "es-define-property": "^1.0.0" + } + }, + "has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true + }, + "has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.3" + } + }, + "hasown": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", + "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", + "dev": true, + "requires": { + "function-bind": "^1.1.2" + } + }, + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "dev": true, + "requires": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + } + }, + "is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "requires": { + "has-bigints": "^1.0.1" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "optional": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "requires": { + "builtin-modules": "^3.3.0" + } + }, + "is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true + }, + "is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, + "requires": { + "hasown": "^2.0.0" + } + }, + "is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "optional": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "dev": true + }, + "is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "optional": true + }, + "is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dev": true, + "requires": { + "call-bind": "^1.0.7" + } + }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, + "requires": { + "which-typed-array": "^1.1.14" + } + }, + "is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "requires": { + "@isaacs/cliui": "^8.0.2", + "@pkgjs/parseargs": "^0.11.0" + } + }, + "jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true + } + } + }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "dependencies": { + "semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true + } + } + }, + "memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "dev": true + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true + } + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "optional": true + }, + "npm-run-all": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", + "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "memorystream": "^0.3.1", + "minimatch": "^3.0.4", + "pidtree": "^0.3.0", + "read-pkg": "^3.0.0", + "shell-quote": "^1.6.1", + "string.prototype.padend": "^3.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true + }, + "semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dev": true, + "requires": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", + "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "dev": true + } + } + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true + } + } + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "pidtree": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", + "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", + "dev": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "optional": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "dev": true, + "requires": { + "regenerate": "^1.4.2" + } + }, + "regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true + }, + "regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.8.4" + } + }, + "regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "dev": true, + "requires": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + } + }, + "regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "dev": true, + "requires": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + } + }, + "regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "dev": true + } + } + }, + "resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "requires": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "rimraf": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", + "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", + "dev": true, + "requires": { + "glob": "^10.3.7" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "requires": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + } + }, + "minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, + "rollup": { + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "dev": true, + "requires": { + "fsevents": "~2.3.2" + } + }, + "rollup-plugin-terser": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", + "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "jest-worker": "^26.2.1", + "serialize-javascript": "^4.0.0", + "terser": "^5.0.0" + } + }, + "safe-array-concat": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.0.tgz", + "integrity": "sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==", + "dev": true, + "requires": { + "call-bind": "^1.0.5", + "get-intrinsic": "^1.2.2", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dev": true, + "requires": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + } + }, + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true + }, + "serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "set-function-length": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", + "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", + "dev": true, + "requires": { + "define-data-property": "^1.1.2", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.1" + } + }, + "set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "requires": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true + }, + "side-channel": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz", + "integrity": "sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + } + }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true + }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz", + "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==", + "dev": true + }, + "string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + }, + "string-width-cjs": { + "version": "npm:string-width@4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, + "string.prototype.padend": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.5.tgz", + "integrity": "sha512-DOB27b/2UTTD+4myKUFh+/fXWcu/UDyASIXfg+7VzoCNNGOfWvoyU/x5pvVHr++ztyt/oSYI1BcWBBG/hmlNjA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + } + }, + "string.prototype.trim": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", + "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + } + }, + "string.prototype.trimend": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", + "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + } + }, + "string.prototype.trimstart": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", + "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + } + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + }, + "strip-ansi-cjs": { + "version": "npm:strip-ansi@6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + } + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "terser": { + "version": "5.28.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.28.1.tgz", + "integrity": "sha512-wM+bZp54v/E9eRRGXb5ZFDvinrJIOaTapx3WUokyVGZu5ucVCK55zEgGd5Dl2fSr3jUo5sDiERErUWLY6QPFyA==", + "dev": true, + "requires": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + } + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "optional": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + } + }, + "typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + } + }, + "typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + } + }, + "typed-array-length": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.5.tgz", + "integrity": "sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + } + }, + "typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "dev": true + }, + "unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + } + }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "dev": true + }, + "unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "requires": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "dev": true + }, + "unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true + }, + "update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "dev": true, + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "which-typed-array": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.14.tgz", + "integrity": "sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.6", + "call-bind": "^1.0.5", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.1" + } + }, + "wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "requires": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true + } + } + }, + "wrap-ansi-cjs": { + "version": "npm:wrap-ansi@7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + } + } +} diff --git a/bindings/js/package.json b/bindings/js/package.json new file mode 100644 index 000000000..ba9a20b6b --- /dev/null +++ b/bindings/js/package.json @@ -0,0 +1,46 @@ +{ + "name": "depthai-js", + "version": "0.0.1", + "description": "depthai-core JS bindings", + "author": "Luxonis ", + "keywords": [], + "license": "MIT", + "main": "lib/cjs/index.js", + "module": "lib/index.js", + "exports": { + ".": "./lib/index.js" + }, + "types": "./lib/index.d.ts", + "files": [ + "lib/**/*", + "README.md" + ], + "repository": { + "type": "git", + "url": "https://github.com/luxonis/depthai-core" + }, + "scripts": { + "clean": "rimraf lib", + "build:esm": "cross-env BABEL_ENV=esmUnbundled babel src --extensions '.ts' --out-dir 'lib'", + "build:cjs": "cross-env BABEL_ENV=cjs babel src --extensions '.ts' --out-dir 'lib/cjs'", + "build:esmBundled": "cross-env BABEL_ENV=esmBundled rollup -c rollup.config.js", + "build:umdBundled": "cross-env BABEL_ENV=umdBundled rollup -c rollup.config.js", + "build:declarations": "tsc -p tsconfig.json", + "build:copyFiles": "mkdir -p lib && cp src/*.js src/*.d.ts lib/", + "build": "npm-run-all -l clean -p build:esm build:cjs build:esmBundled build:umdBundled build:declarations build:copyFiles" + }, + "devDependencies": { + "@babel/cli": "^7.23.9", + "@babel/core": "^7.24.0", + "@babel/preset-env": "^7.24.0", + "@babel/preset-typescript": "^7.23.3", + "@rollup/plugin-babel": "^6.0.4", + "@rollup/plugin-node-resolve": "^15.2.3", + "cross-env": "^7.0.3", + "npm-run-all": "^4.1.5", + "rimraf": "^5.0.5", + "rollup": "^2.79.1", + "rollup-plugin-terser": "^7.0.2", + "typescript": "^5.3.3" + } +} diff --git a/bindings/js/rollup.config.js b/bindings/js/rollup.config.js new file mode 100644 index 000000000..7c88afe0c --- /dev/null +++ b/bindings/js/rollup.config.js @@ -0,0 +1,46 @@ +import babel from "@rollup/plugin-babel"; +import { nodeResolve } from "@rollup/plugin-node-resolve"; +import { terser } from "rollup-plugin-terser"; + +console.log(` +------------------------------------- +Rollup building bundle for ${process.env.BABEL_ENV} +------------------------------------- +`); + +const extensions = [".js", ".ts"]; + +export default { + input: "src/index.ts", + output: [ + ...(process.env.BABEL_ENV === "esmBundled" + ? [ + { + file: "lib/bundles/bundle.esm.min.js", + format: "esm", + sourcemap: true, + }, + ] + : []), + ...(process.env.BABEL_ENV === "umdBundled" + ? [ + { + file: "lib/bundles/bundle.umd.min.js", + format: "umd", + name: "my-lib", + sourcemap: true, + }, + ] + : []), + ], + plugins: [ + nodeResolve({ extensions }), + babel({ + babelHelpers: "bundled", + include: ["src/**/*.ts", "src/**/*.js"], + extensions, + exclude: "./node_modules/**", + }), + terser(), + ], +}; diff --git a/bindings/js/src/.gitignore b/bindings/js/src/.gitignore new file mode 100644 index 000000000..ec7b9688a --- /dev/null +++ b/bindings/js/src/.gitignore @@ -0,0 +1,2 @@ +/depthai-js.d.ts +/depthai-js.js diff --git a/bindings/js/src/index.ts b/bindings/js/src/index.ts new file mode 100644 index 000000000..3c9c0866a --- /dev/null +++ b/bindings/js/src/index.ts @@ -0,0 +1,76 @@ +import depthaiJsModuleInitialize, { + DatatypeEnum, + Uint8Vector, + MainModule, +} from "./depthai-js.js"; + +export * from "./depthai-js.js"; + +interface ParsedMessage { + type: DatatypeEnum; + metadata: Uint8Array; + data: Uint8Array; +} + +export type Dai = MainModule; + +let dai: { value: Dai | null } = { value: null }; +async function initialize(): Promise { + const depthai = (await (depthaiJsModuleInitialize as any)()) as Dai; + dai.value = depthai; + return depthai; +} + +export function arrayToVector(byteArray: Uint8Array): Uint8Vector { + if (dai.value === null) { + throw Error(); + } + const bytes = new dai.value.Uint8Vector(); + byteArray.forEach((element) => { + bytes.push_back(element); + }); + return bytes; +} + +export function parseMessage(arrayBuffer: ArrayBuffer): ParsedMessage { + if (dai.value === null) { + throw Error(); + } + if (arrayBuffer.byteLength < 8) { + throw Error(); + } + const headerArray = new Uint8Array( + arrayBuffer, + arrayBuffer.byteLength - 8, + 8 + ); + const headerBytes = arrayToVector(headerArray); + const header = dai.value.getMessageType(headerBytes); + const dataLength = + arrayBuffer.byteLength - // whole packet + 8 - // header + header.serializedObjectSize; // metadata + if (dataLength < 0) { + throw Error( + "Invalid data length: " + + dataLength + + " = " + + arrayBuffer.byteLength + + " - 8 - " + + header.serializedObjectSize + ); + } + const data = new Uint8Array(arrayBuffer, 0, dataLength); + const metadata = new Uint8Array( + arrayBuffer, + dataLength, + header.serializedObjectSize + ); + return { + type: header.objectType, + data, + metadata, + }; +} + +export default initialize; diff --git a/bindings/js/tsconfig.json b/bindings/js/tsconfig.json new file mode 100644 index 000000000..f9f0c5d4f --- /dev/null +++ b/bindings/js/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "outDir": "lib", + "target": "es6", + "module": "esnext", + "moduleResolution": "node", + "lib": [ + "es2015", + "dom" + ], + "sourceMap": true, + "strict": true, + "strictFunctionTypes": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "noImplicitAny": true, + "strictNullChecks": true, + "alwaysStrict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "skipLibCheck": true, + "declaration": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true + }, + "include": ["src"], + "exclude": ["node_modules", "lib", "**/*.test.ts"] +} diff --git a/bindings/python/.gitignore b/bindings/python/.gitignore new file mode 100644 index 000000000..8b2403a39 --- /dev/null +++ b/bindings/python/.gitignore @@ -0,0 +1,49 @@ +# Microsoft Visual Studio Code +.project +.vscode/ +.vs/ +build*/* +# Auto-generated +generated/* + +#pybind11 +pybind11-2.5.0/ +build/ +dist/ +_build/ +_generate/ +*.so +*.py[cod] +*.egg-info + +#depthai c++ core library +depthai-core/.vscode/ +depthai-core/build/ + +# builds +_builds/ + +#git +*.orig +*_REMOTE_* +*_LOCAL_* +*_BACKUP_* +*_BASE_* + +#ci +wheelhouse/ + +# Environments +.env +.venv +env/ +venv/ +venv_*/ +ENV/ +env.bak/ +venv.bak/ + +# PyCharm +.idea/ +#Clang +.cache/ diff --git a/bindings/python/CMakeLists.txt b/bindings/python/CMakeLists.txt new file mode 100644 index 000000000..631f7a5f2 --- /dev/null +++ b/bindings/python/CMakeLists.txt @@ -0,0 +1,338 @@ +cmake_minimum_required(VERSION 3.4) # For Hunter + +# Set policies +# CMP0074 dictates that find_package searches environment variable "[packageName]_ROOT" along with regular variable [packageName]_ROOT +if(POLICY CMP0074) + cmake_policy(SET CMP0074 NEW) # Only introduced in 3.12 +endif() + +if(POLICY CMP0028) + cmake_policy(SET CMP0028 NEW) +endif() + +# Specify path separator +set(SYS_PATH_SEPARATOR ";") +if(UNIX) + set(SYS_PATH_SEPARATOR ":") +endif() + +# Move binary dir if windows, to shorten the path +if(WIN32) + set(HUNTER_BINARY_DIR "${HUNTER_GATE_ROOT}/_bin" CACHE STRING "Hunter binary directory") +endif() + +# Pybindings project +set(TARGET_NAME depthai) +project(depthai VERSION "0") # revision of bindings [depthai-core].[rev] + +# Add module paths +list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/") + +# Constants +set(DOCSTRINGS_INCLUDE_PLACEHOLDER_DIR ${CMAKE_CURRENT_BINARY_DIR}/generated/include) +set(DOCSTRINGS_INCLUDE_PLACEHOLDER_PATH ${DOCSTRINGS_INCLUDE_PLACEHOLDER_DIR}/docstring.hpp) +set(DEFAULT_DOCSTRINGS_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/generated/depthai_python_docstring.hpp) + +# First specify options +# option(DEPTHAI_PYTHON_USE_FIND_PACKAGE "Use find_package for depthai-core" OFF) +option(DEPTHAI_PYTHON_ENABLE_TESTS "Enable tests" OFF) +option(DEPTHAI_PYTHON_ENABLE_EXAMPLES "Enable examples" OFF) +option(DEPTHAI_PYTHON_BUILD_DOCS "Build documentation - see docs/requirements.txt for needed dependencies" OFF) +option(DEPTHAI_PYTHON_BUILD_DOCSTRINGS "Generate docstrings from header files if module 'pybind11_mkdoc' available" ON) +option(DEPTHAI_PYTHON_EMBEDDED_MODULE "Create an embeddable module" OFF) + +# Add pybind11 dependency +#add_subdirectory(pybind11-2.5.0) +hunter_add_package(pybind11) + +# Disable LTO if MINGW compiler +if(MINGW) + set(PYBIND11_LTO_CXX_FLAGS "" CACHE STRING "" FORCE) +endif() +find_package(pybind11 CONFIG REQUIRED) + +# Add external dependencies +add_subdirectory(external) + +set(SOURCE_LIST + src/py_bindings.cpp + src/XLinkBindings.cpp + src/DeviceBindings.cpp + src/CalibrationHandlerBindings.cpp + src/DeviceBootloaderBindings.cpp + src/DatatypeBindings.cpp + src/DataQueueBindings.cpp + src/pipeline/PipelineBindings.cpp + src/pipeline/CommonBindings.cpp + src/pipeline/AssetManagerBindings.cpp + src/openvino/OpenVINOBindings.cpp + src/log/LogBindings.cpp + src/VersionBindings.cpp + + src/pipeline/node/NodeBindings.cpp + + src/pipeline/node/XLinkInBindings.cpp + src/pipeline/node/XLinkOutBindings.cpp + src/pipeline/node/ColorCameraBindings.cpp + src/pipeline/node/CameraBindings.cpp + src/pipeline/node/MonoCameraBindings.cpp + src/pipeline/node/StereoDepthBindings.cpp + src/pipeline/node/NeuralNetworkBindings.cpp + src/pipeline/node/VideoEncoderBindings.cpp + src/pipeline/node/ImageManipBindings.cpp + src/pipeline/node/SPIOutBindings.cpp + src/pipeline/node/SPIInBindings.cpp + src/pipeline/node/DetectionNetworkBindings.cpp + src/pipeline/node/SystemLoggerBindings.cpp + src/pipeline/node/ScriptBindings.cpp + src/pipeline/node/SpatialLocationCalculatorBindings.cpp + src/pipeline/node/SpatialDetectionNetworkBindings.cpp + src/pipeline/node/ObjectTrackerBindings.cpp + src/pipeline/node/IMUBindings.cpp + src/pipeline/node/EdgeDetectorBindings.cpp + src/pipeline/node/FeatureTrackerBindings.cpp + src/pipeline/node/ToFBindings.cpp + src/pipeline/node/AprilTagBindings.cpp + src/pipeline/node/DetectionParserBindings.cpp + src/pipeline/node/WarpBindings.cpp + src/pipeline/node/SyncBindings.cpp + src/pipeline/node/BenchmarkBindings.cpp + src/pipeline/node/UVCBindings.cpp + src/pipeline/node/ToFBindings.cpp + src/pipeline/node/PointCloudBindings.cpp + src/pipeline/node/SyncBindings.cpp + src/pipeline/node/MessageDemuxBindings.cpp + + src/pipeline/datatype/ADatatypeBindings.cpp + src/pipeline/datatype/AprilTagConfigBindings.cpp + src/pipeline/datatype/AprilTagsBindings.cpp + src/pipeline/datatype/BufferBindings.cpp + src/pipeline/datatype/CameraControlBindings.cpp + src/pipeline/datatype/EdgeDetectorConfigBindings.cpp + src/pipeline/datatype/FeatureTrackerConfigBindings.cpp + src/pipeline/datatype/ToFConfigBindings.cpp + src/pipeline/datatype/ImageManipConfigBindings.cpp + src/pipeline/datatype/ImgDetectionsBindings.cpp + src/pipeline/datatype/ImgFrameBindings.cpp + src/pipeline/datatype/EncodedFrameBindings.cpp + src/pipeline/datatype/IMUDataBindings.cpp + src/pipeline/datatype/MessageGroupBindings.cpp + src/pipeline/datatype/NNDataBindings.cpp + src/pipeline/datatype/SpatialImgDetectionsBindings.cpp + src/pipeline/datatype/SpatialLocationCalculatorConfigBindings.cpp + src/pipeline/datatype/SpatialLocationCalculatorDataBindings.cpp + src/pipeline/datatype/StereoDepthConfigBindings.cpp + src/pipeline/datatype/SystemInformationBindings.cpp + src/pipeline/datatype/TrackedFeaturesBindings.cpp + src/pipeline/datatype/TrackletsBindings.cpp + src/pipeline/datatype/BenchmarkReportBindings.cpp + src/pipeline/datatype/PointCloudConfigBindings.cpp + src/pipeline/datatype/PointCloudDataBindings.cpp +) + +# Add files for python module +if(DEPTHAI_PYTHON_EMBEDDED_MODULE) + add_library(${TARGET_NAME} ${SOURCE_LIST}) +else() + pybind11_add_module(${TARGET_NAME} ${SOURCE_LIST}) +endif() + +if(WIN32) + # Copy dlls to target directory - Windows only + # TARGET_RUNTIME_DLLS generator expression available since CMake 3.21 + if(CMAKE_VERSION VERSION_LESS "3.21") + file(GLOB depthai_dll_libraries "${HUNTER_INSTALL_PREFIX}/bin/*.dll") + else() + set(depthai_dll_libraries "$") + endif() + add_custom_command(TARGET ${TARGET_NAME} POST_BUILD COMMAND + "$<$:${CMAKE_COMMAND};-E;copy_if_different;${depthai_dll_libraries};$>" + COMMAND_EXPAND_LISTS + VERBATIM + ) + + # Disable "d" postfix, so python can import the library as is + set_target_properties(${TARGET_NAME} PROPERTIES DEBUG_POSTFIX "") +endif() + +# Add stubs (pyi) generation step after building bindings +execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c" "from mypy import api" RESULT_VARIABLE error OUTPUT_QUIET ERROR_QUIET) +if(error OR CMAKE_CROSSCOMPILING) + message(WARNING "Mypy not available or cross compiling - stubs won't be generated or checked") +else() + get_target_property(bindings_directory ${TARGET_NAME} LIBRARY_OUTPUT_DIRECTORY) + if(NOT bindings_directory) + set(bindings_directory ${CMAKE_CURRENT_BINARY_DIR}) + endif() + message(STATUS "Mypy available, creating and checking stubs. Running with generate_stubs.py ${TARGET_NAME} ${bindings_directory}") + add_custom_command(TARGET ${TARGET_NAME} POST_BUILD COMMAND + ${CMAKE_COMMAND} -E env + # Python path (to find compiled module) + "PYTHONPATH=$${SYS_PATH_SEPARATOR}$ENV{PYTHONPATH}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_LIST_DIR}/generate_stubs.py" "${TARGET_NAME}" "$" + DEPENDS "${CMAKE_CURRENT_LIST_DIR}/generate_stubs.py" + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + ) +endif() + +# Docstring options +if(DEPTHAI_PYTHON_DOCSTRINGS_INPUT AND DEPTHAI_PYTHON_DOCSTRINGS_OUTPUT) + message(FATAL_ERROR "DEPTHAI_PYTHON_DOCSTRINGS_INPUT and DEPTHAI_PYTHON_DOCSTRINGS_OUTPUT are mutually exclusive") +endif() + +if(DEPTHAI_PYTHON_DOCSTRINGS_OUTPUT) + # If output is specified set both input and output to same the path + set(docstring_input_path ${DEPTHAI_PYTHON_DOCSTRINGS_OUTPUT}) + set(docstring_output_path ${DEPTHAI_PYTHON_DOCSTRINGS_OUTPUT}) +else() + # If input docstrings explicitly specified, use those and disable building + if(DEPTHAI_PYTHON_DOCSTRINGS_INPUT) + set(docstring_input_path ${DEPTHAI_PYTHON_DOCSTRINGS_INPUT}) + message(STATUS "Disabled building of docstrings - using docstrings specified by DEPTHAI_PYTHON_DOCSTRINGS_INPUT (${DEPTHAI_PYTHON_DOCSTRINGS_INPUT})") + set(DEPTHAI_PYTHON_BUILD_DOCSTRINGS OFF CACHE BOOL "Generate docstrings from header files if module 'pybind11_mkdoc' available" FORCE) + else() + # Otherwise set default location as input + set(docstring_input_path ${DEFAULT_DOCSTRINGS_OUTPUT}) + endif() + + # Set default output location + set(docstring_output_path ${DEFAULT_DOCSTRINGS_OUTPUT}) +endif() + +if(DEPTHAI_PYTHON_BUILD_DOCSTRINGS) + option(DEPTHAI_PYTHON_FORCE_DOCSTRINGS "Force that docstrings are generated, module 'pybind11_mkdoc' required" OFF) +endif() + +# Configure include placeholder with INPUT path +configure_file(cmake/docstring.hpp.in ${DOCSTRINGS_INCLUDE_PLACEHOLDER_PATH}) +# Add target to generate docstrings +if (DEPTHAI_PYTHON_BUILD_DOCSTRINGS) + include(pybind11-mkdoc) + + # Check if pybind11_mkdoc available and create target + target_pybind11_mkdoc_setup(${docstring_output_path} depthai::core ${DEPTHAI_PYTHON_FORCE_DOCSTRINGS}) + + if(TARGET pybind11_mkdoc) + # Add dependency to mkdoc target (makes sure that mkdoc is executed, and docstrings available) + add_dependencies(${TARGET_NAME} pybind11_mkdoc) + else() + # Generate default docstrings to OUTPUT path + configure_file(cmake/default_docstring.hpp.in ${docstring_output_path} COPYONLY) + endif() +else() + # Generate default docstrings to OUTPUT path + configure_file(cmake/default_docstring.hpp.in ${docstring_output_path} COPYONLY) +endif() + +# Add include directory +target_include_directories(${TARGET_NAME} PRIVATE src ${DOCSTRINGS_INCLUDE_PLACEHOLDER_DIR}) + +# Link with libraries +target_link_libraries(${TARGET_NAME} + PUBLIC + # pybind11 + pybind11::pybind11 + depthai::core # Use non-opencv target as we use opencv-python in bindings + hedley + pybind11_json + xtensor-python +) + +# Add embedded module option, otherwise link to pybind11 as usual +if(DEPTHAI_PYTHON_EMBEDDED_MODULE) + target_compile_definitions(${TARGET_NAME} PRIVATE DEPTHAI_PYTHON_EMBEDDED_MODULE) +endif() + +# Find Git +find_package(Git) + +# Add build information (commit, date) +set(BUILD_COMMIT "dev") +if(GIT_FOUND) + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse HEAD + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} + OUTPUT_VARIABLE BUILD_COMMIT + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + execute_process( + COMMAND ${GIT_EXECUTABLE} show -s --format=%ci ${BUILD_COMMIT} + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} + OUTPUT_VARIABLE BUILD_COMMIT_DATETIME + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) +endif() + +# Add local commit hash (or 'dev' if unable to retrieve) if not build by CI +if(NOT DEFINED ENV{CI} AND NOT DEPTHAI_PYTHON_COMMIT_HASH) + set(DEPTHAI_PYTHON_COMMIT_HASH ${BUILD_COMMIT}) +endif() + +# Get version to use +set(version_command "import find_version as v; print(v.get_package_version())") +if(DEPTHAI_PYTHON_COMMIT_HASH) + set(version_command "import find_version as v; print(v.get_package_dev_version('${DEPTHAI_PYTHON_COMMIT_HASH}'))") +endif() +execute_process(COMMAND ${PYTHON_EXECUTABLE} "-c" "${version_command}" + OUTPUT_VARIABLE DEPTHAI_PYTHON_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} +) + + +string(TIMESTAMP BUILD_DATETIME "%Y-%m-%d %H:%M:%S +0000" UTC) +target_compile_definitions(${TARGET_NAME} + PRIVATE + DEPTHAI_PYTHON_VERSION="${DEPTHAI_PYTHON_VERSION}" + DEPTHAI_PYTHON_COMMIT_HASH="${BUILD_COMMIT}" + DEPTHAI_PYTHON_COMMIT_DATETIME="${BUILD_COMMIT_DATETIME}" + DEPTHAI_PYTHON_BUILD_DATETIME="${BUILD_DATETIME}" +) + +# ASAN Settings as we are building and using shared library +if(SANITIZE_ADDRESS OR SANITIZE_MEMORY OR SANITIZE_THREAD OR SANITIZE_UNDEFINED) + # Get asan library to preload + if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + execute_process(COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=libclang_rt.asan-${CMAKE_HOST_SYSTEM_PROCESSOR}.so OUTPUT_VARIABLE LIBASAN_PATH OUTPUT_STRIP_TRAILING_WHITESPACE) + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + execute_process(COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=libasan.so OUTPUT_VARIABLE LIBASAN_PATH OUTPUT_STRIP_TRAILING_WHITESPACE) + endif() + # Set preload env variable + if(APPLE) + set(ASAN_ENVIRONMENT_VARS "DYLD_INSERT_LIBRARIES=${LIBASAN_PATH}" "ASAN_OPTIONS=leak_check_at_exit=0") + elseif(UNIX) + set(ASAN_ENVIRONMENT_VARS "LD_PRELOAD=${LIBASAN_PATH}" "ASAN_OPTIONS=leak_check_at_exit=0") + endif() + message(STATUS "ASAN environment variables: ${ASAN_ENVIRONMENT_VARS}") +endif() + +######################## +# Testing +######################## +if(DEPTHAI_PYTHON_ENABLE_TESTS OR DEPTHAI_PYTHON_ENABLE_EXAMPLES) + include(CTest) + enable_testing() +endif() + +######################## +# Tests +######################## +if (DEPTHAI_PYTHON_ENABLE_TESTS) + add_subdirectory(tests) +endif() + +######################## +# Examples (can also act as tests) +######################## +if (DEPTHAI_PYTHON_ENABLE_EXAMPLES) + add_subdirectory(examples) +endif() + +######################## +# Documentation +######################## +if(DEPTHAI_PYTHON_BUILD_DOCS) + add_subdirectory(docs) +endif() diff --git a/bindings/python/LICENSE b/bindings/python/LICENSE new file mode 100644 index 000000000..b45d6ba17 --- /dev/null +++ b/bindings/python/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Luxonis LLC + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/bindings/python/MANIFEST.in b/bindings/python/MANIFEST.in new file mode 100644 index 000000000..536965148 --- /dev/null +++ b/bindings/python/MANIFEST.in @@ -0,0 +1,17 @@ +include README.md LICENSE CMakeLists.txt pyproject.toml +include find_version.py +include generate_stubs.py +graft cmake +graft generated +graft ci +graft external +graft src +graft depthai-core +prune depthai-core/build* +prune depthai-core/tests* +prune depthai-core/examples* +prune build +prune wheelhouse +prune dist +prune tests +prune examples diff --git a/bindings/python/README.md b/bindings/python/README.md new file mode 100644 index 000000000..dbd060a5e --- /dev/null +++ b/bindings/python/README.md @@ -0,0 +1,223 @@ +# DepthAI Python Library + +[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT) +[![](https://img.shields.io/pypi/v/depthai.svg)](https://pypi.org/project/depthai/) +[![Python Wheel CI](https://github.com/luxonis/depthai-python/actions/workflows/main.yml/badge.svg?branch=gen2_develop)](https://github.com/luxonis/depthai-python/actions/workflows/main.yml) + +Python bindings for C++ depthai-core library + +## Documentation + +Documentation is available over at [Luxonis DepthAI API](https://docs.luxonis.com/projects/api/en/latest/) + +## Installation + +Prebuilt wheels are available in [Luxonis repository](https://artifacts.luxonis.com/artifactory/luxonis-python-snapshot-local/) +Make sure pip is upgraded +``` +python3 -m pip install -U pip +python3 -m pip install --extra-index-url https://artifacts.luxonis.com/artifactory/luxonis-python-snapshot-local/ depthai +``` +## Building from source + +### Dependencies + - cmake >= 3.4 + - C++14 compiler (clang, gcc, msvc, ...) + - Python3 + +Along these, dependencies of depthai-core are also required +See: [depthai-core dependencies](https://github.com/luxonis/depthai-core#dependencies) + + +### Building + +The first time you build, the repository submodules need be initialized: +``` +git submodule update --init --recursive + +# Tip: You can ask Git to do that automatically: +git config submodule.recurse true +``` + +Later submodules also need to be updated. + +#### Local build with pip +To build and install using pip: +``` +cd dephai-core/bindings/python +python3 -m pip install . +``` +Add parameter `-v` to see the output of the building process. + +#### Wheel with pip +To build a wheel, execute the following +``` +cd depthai-core/bindings/python +python3 -m pip wheel . -w wheelhouse +``` + +#### Shared library +To build a shared library from source perform the following: + +> â„¹ï¸ To speed up build times, use `cmake --build build --parallel [num CPU cores]` (CMake >= 3.12). +For older versions use: Linux/macOS: `cmake --build build -- -j[num CPU cores]`, MSVC: `cmake --build build -- /MP[num CPU cores]` + +``` +cd depthai-core +cmake -H. -Bbuild -DDEPTHAI_BUILD_PYTHON=ON +cmake --build build +``` +To specify custom Python executable to build for, use `cmake -H. -Bbuild -D PYTHON_EXECUTABLE=/full/path/to/python`. + +#### Common issues + +* Many build fails due to missing dependencies. This also happens when submodules are missing or outdated (`git submodule update --recursive`). +* If libraries and headers are not in standard places, or not on the search paths, CMake reports it cannot find what it needs (e.g. `libusb`). CMake can be hinted at where to look, for exmpale: `CMAKE_LIBRARY_PATH=/opt/local/lib CMAKE_INCLUDE_PATH=/opt/local/include pip install .` +* Some distribution installers may not get the desired library. For example, an install on a RaspberryPi failed, missing `libusb`, as the default installation with APT led to v0.1.3 at the time, whereas the library here required v1.0. + + +## Running tests + +To run the tests build the library with the following options +``` +git submodule update --init --recursive +cmake -H. -Bbuild -D DEPTHAI_PYTHON_ENABLE_TESTS=ON -D DEPTHAI_PYTHON_ENABLE_EXAMPLES=ON -D DEPTHAI_PYTHON_TEST_EXAMPLES=ON +cmake --build build +``` + +Then navigate to `build` folder and run `ctest` +``` +cd build +ctest +``` + +To test a specific example/test with a custom timeout (in seconds) use following: +``` +TEST_TIMEOUT=0 ctest -R "01_rgb_preview" --verbose +``` +If `TEST_TIMEOUT=0`, the test will run until stopped or it ends. + +## Tested platforms + +- Windows 10, Windows 11 +- Ubuntu 18.04, 20.04, 22.04; +- Raspbian 10; +- macOS 10.14.6, 10.15.4; + +### Building documentation + +- **Using [Docker](https://docs.docker.com/) (with [Docker Compose](https://docs.docker.com/compose/install/))** + + ``` + cd docs + sudo docker-compose build + sudo docker-compose up + ``` + + > â„¹ï¸ You can leave out the `sudo` if you have added your user to the `docker` group (or are using rootless docker). + Then open [http://localhost:8000](http://localhost:8000). + + This docker container will watch changes in the `docs/source` directory and rebuild the docs automatically + +- **Linux** + + First, please install the required [dependencies](#Dependencies) + + Then run the following commands to build the docs website + + ``` + python3 -m pip install -U pip + python3 -m pip install -r docs/requirements.txt + cmake -H. -Bbuild -D DEPTHAI_BUILD_DOCS=ON -D DEPTHAI_PYTHON_BUILD_DOCS=ON + cmake --build build --target sphinx + python3 -m http.server --bind 0.0.0.0 8000 --directory build/docs/sphinx + ``` + + Then open [http://localhost:8000](http://localhost:8000). + + This will build documentation based on current sources, so if some new changes will be made, run this command + in a new terminal window to update the website source + + ``` + cmake --build build --target sphinx + ``` + + Then refresh your page - it should load the updated website that was just built + +## Troubleshooting + +### Relocation link error + +Build failure on Ubuntu 18.04 ("relocation ..." link error) with gcc 7.4.0 (default) - [**issue #3**](https://github.com/luxonis/depthai-api/issues/3) + - the solution was to upgrade gcc to version 8: + + sudo apt install g++-8 + sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 70 + sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-8 70 +### Hunter +Hunter is a CMake-only dependency manager for C/C++ projects. + +If you are stuck with error message which mentions external libraries (subdirectory of `.hunter`) like the following: +``` +/usr/bin/ld: /home/[user]/.hunter/_Base/062a19a/ccfed35/a84a713/Install/lib/liblzma.a(stream_flags_decoder.c.o): warning: relocation against `lzma_footer_magic' in read-only section `.text' +``` + +Try erasing the **Hunter** **cache** folder. + +Linux/MacOS: +``` +rm -r ~/.hunter +``` +Windows: +``` +del C:/.hunter +``` +or +``` +del C:/[user]/.hunter +``` + +### LTO - link time optimization + +If following message appears: +``` +lto1: internal compiler error: in add_symbol_to_partition_1, at lto/lto-partition.c:152 +Please submit a full bug report, +with preprocessed source if appropriate. +See for instructions. +lto-wrapper: fatal error: /usr/bin/c++ returned 1 exit status +compilation terminated. +/usr/bin/ld: error: lto-wrapper failed +collect2: error: ld returned 1 exit status +make[2]: *** [CMakeFiles/depthai.dir/build.make:227: depthai.cpython-38-x86_64-linux-gnu.so] Error 1 +make[1]: *** [CMakeFiles/Makefile2:98: CMakeFiles/depthai.dir/all] Error 2 +make: *** [Makefile:130: all] Error 2 +``` + +One fix is to update linker: (In case you are on Ubuntu 20.04: `/usr/bin/ld --version`: 2.30) +``` +# Add to the end of /etc/apt/sources.list: + +echo "deb http://ro.archive.ubuntu.com/ubuntu groovy main" >> /etc/apt/sources.list + +# Replace ro with your countries local cache server (check the content of the file to find out which is) +# Not mandatory, but faster + +sudo apt update +sudo apt install binutils + +# Should upgrade to 2.35.1 +# Check version: +/usr/bin/ld --version +# Output should be: GNU ld (GNU Binutils for Ubuntu) 2.35.1 +# Revert /etc/apt/sources.list to previous state (comment out line) to prevent updating other packages. +sudo apt update +``` + +Another option is to use **clang** compiler: +``` +sudo apt install clang-10 +mkdir build && cd build +CC=clang-10 CXX=clang++-10 cmake .. +cmake --build . --parallel +``` diff --git a/bindings/python/ci/Dockerfile b/bindings/python/ci/Dockerfile new file mode 100644 index 000000000..4d21d1ba0 --- /dev/null +++ b/bindings/python/ci/Dockerfile @@ -0,0 +1,18 @@ +FROM python:3.9-bullseye + +RUN apt-get update && apt-get install -y wget build-essential cmake pkg-config libjpeg-dev libtiff5-dev libavcodec-dev libavformat-dev libswscale-dev libv4l-dev libxvidcore-dev libx264-dev libgtk2.0-dev libgtk-3-dev libatlas-base-dev gfortran git libopencv-dev + +ADD ci/docker_dependencies.sh . +RUN ./docker_dependencies.sh + +RUN pip install -U pip && pip install --extra-index-url https://www.piwheels.org/simple/ --prefer-binary opencv-python + +# Copy over the files +COPY . /depthai-core + +# Install C++ library +RUN cmake -S /depthai-core -B /build -D CMAKE_BUILD_TYPE=Release -D BUILD_SHARED_LIBS=ON -D CMAKE_INSTALL_PREFIX=/usr/local +RUN cmake --build /build --parallel 4 --config Relase --target install + +# Install Python library +RUN cd /depthai-python/bindings/python && python3 -m pip install . diff --git a/bindings/python/ci/build-wheels.sh b/bindings/python/ci/build-wheels.sh new file mode 100755 index 000000000..9f53a546d --- /dev/null +++ b/bindings/python/ci/build-wheels.sh @@ -0,0 +1,25 @@ +#!/bin/bash +set -e -x + +# Install a system package required by our library +#yum install -y atlas-devel +yum install -y libusb1-devel +#yum remove -y libusb1 + +# Compile wheels +for PYBIN in /opt/python/cp3{6..10}*/bin; do + #"${PYBIN}/pip" install -r /io/requirements.txt + "${PYBIN}/pip" wheel /io/ -w wheelhouse/ +done + +# Bundle external shared libraries into the wheels +for whl in wheelhouse/*.whl; do + auditwheel repair "$whl" --plat $PLAT -w /io/wheelhouse/ \ + || echo "Skipping non-platform wheel $whl" +done + +# Install packages and test +#for PYBIN in /opt/python/*/bin/; do +# "${PYBIN}/pip" install python-manylinux-demo --no-index -f /io/wheelhouse +# (cd "$HOME"; "${PYBIN}/nosetests" pymanylinuxdemo) +#done diff --git a/bindings/python/ci/check_format.sh b/bindings/python/ci/check_format.sh new file mode 100755 index 000000000..eb184bf31 --- /dev/null +++ b/bindings/python/ci/check_format.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +# Perform code format (cmake target) +cmake --build "$1" --target clangformat + +# Display diff +git --no-pager diff + +# The following returns non-zero exit code if there is any difference +git diff-index --quiet HEAD -- \ No newline at end of file diff --git a/bindings/python/ci/docker_dependencies.sh b/bindings/python/ci/docker_dependencies.sh new file mode 100755 index 000000000..d3cbfc291 --- /dev/null +++ b/bindings/python/ci/docker_dependencies.sh @@ -0,0 +1,71 @@ +#!/bin/bash + +set -e + +readonly linux_pkgs=( + cmake + git + python3-numpy +) + +readonly ubuntu_pkgs=( + ${linux_pkgs[@]} + # https://docs.opencv.org/master/d7/d9f/tutorial_linux_install.html + build-essential + libgtk2.0-dev + pkg-config + libavcodec-dev + libavformat-dev + libswscale-dev + libtbb2 + libtbb-dev + libjpeg-dev + libpng-dev + libtiff-dev + libdc1394-22-dev + # https://stackoverflow.com/questions/55313610 + ffmpeg + libsm6 + libxext6 + libgl1-mesa-glx +) + +readonly ubuntu_arm_pkgs=( + "${ubuntu_pkgs[@]}" + # https://stackoverflow.com/a/53402396/5494277 + libhdf5-dev + libhdf5-dev + libatlas-base-dev + # https://github.com/EdjeElectronics/TensorFlow-Object-Detection-on-the-Raspberry-Pi/issues/18#issuecomment-433953426 + libilmbase-dev + libopenexr-dev + libgstreamer1.0-dev +) + +print_action () { + green="\e[0;32m" + reset="\e[0;0m" + printf "\n$green >>$reset $*\n" +} +print_and_exec () { + print_action $* + $* +} + +if [ -f /etc/os-release ]; then + # shellcheck source=/etc/os-release + source /etc/os-release + + if [[ ! $(uname -m) =~ ^arm* ]]; then + apt-get update + apt-get install -y "${ubuntu_pkgs[@]}" + python3 -m pip install --upgrade pip + elif [[ $(uname -m) =~ ^arm* ]]; then + apt-get update + apt-get install -y "${ubuntu_arm_pkgs[@]}" + python3 -m pip install --upgrade pip + fi +else + echo "ERROR: Host not supported" + exit 99 +fi diff --git a/bindings/python/ci/repair-whl-macos.sh b/bindings/python/ci/repair-whl-macos.sh new file mode 100755 index 000000000..933f51034 --- /dev/null +++ b/bindings/python/ci/repair-whl-macos.sh @@ -0,0 +1,12 @@ +#!/bin/sh +set -ex +cd $(mktemp -d) +unzip $1 +DYLD_FALLBACK_LIBRARY_PATH=/usr/local/lib delocate-path -L palace.dylibs . +wheel=$(basename $1) +zip -r $wheel * +mkdir -p $2 +mv $wheel $2 +tempdir=$(pwd) +cd - +rm -rf $tempdir \ No newline at end of file diff --git a/bindings/python/ci/stability_stress_test_combined.sh b/bindings/python/ci/stability_stress_test_combined.sh new file mode 100755 index 000000000..207e28e2d --- /dev/null +++ b/bindings/python/ci/stability_stress_test_combined.sh @@ -0,0 +1,38 @@ +# Cleanup in case the script dies +cleanup() { + # kill all processes whose parent is this process + pkill -P $$ +} + +for sig in INT QUIT HUP TERM; do + trap " + cleanup + trap - $sig EXIT + kill -s $sig "'"$$"' "$sig" +done +trap cleanup EXIT + +# Print timeout if set, otherwise use default +echo "Timeout set to: $1" + +# Run USB & PoE stability stress test +DEPTHAI_PROTOCOL=usb timeout $(($1+30)) ./tests/stability_stress_test $1 & +jobUsb=$! +DEPTHAI_PROTOCOL=tcpip timeout $(($1+30)) ./tests/stability_stress_test $1 & +jobTcpip=$! + +# Wait for tests and save result code +wait $jobUsb ; resultUsb=$? +wait $jobTcpip ; resultTcpip=$? + +# Print results +echo "Stability test USB: $resultUsb" +echo "Stability test PoE: $resultTcpip" + +# If both tests concluded successfully, exit with code 0 +if [[ "$resultUsb" == "0" ]] && [[ "$resultTcpip" == "0" ]]; then + echo "Success!" + exit 0 +fi +echo "Failed!" +exit 1 diff --git a/bindings/python/ci/upload-artifactory-release.sh b/bindings/python/ci/upload-artifactory-release.sh new file mode 100755 index 000000000..6669bcace --- /dev/null +++ b/bindings/python/ci/upload-artifactory-release.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +curl -fL https://getcli.jfrog.io | sh + +cd wheelhouse/audited/ || exit 1 +export PATH_PREFIX=luxonis-python-release-local/depthai + +../../jfrog config add --artifactory-url=$ARTIFACTORY_URL --user=$ARTIFACTORY_USER --password=$ARTIFACTORY_PASS +../../jfrog rt u "*" "$PATH_PREFIX/" diff --git a/bindings/python/ci/upload-artifactory.sh b/bindings/python/ci/upload-artifactory.sh new file mode 100755 index 000000000..b00b77323 --- /dev/null +++ b/bindings/python/ci/upload-artifactory.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +curl -fL https://getcli.jfrog.io | sh + +cd wheelhouse/audited/ || exit 1 +export PATH_PREFIX=luxonis-python-snapshot-local/depthai + +../../jfrog config add --artifactory-url=$ARTIFACTORY_URL --user=$ARTIFACTORY_USER --password=$ARTIFACTORY_PASS +../../jfrog rt u "*" "$PATH_PREFIX/" diff --git a/bindings/python/ci/upload-pypi.sh b/bindings/python/ci/upload-pypi.sh new file mode 100755 index 000000000..9c577a4b1 --- /dev/null +++ b/bindings/python/ci/upload-pypi.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +python3 -m pip install -U pip +python3 -m pip install -U setuptools +python3 -m pip install -U twine + +# Uploads prebuilt binary distribution +for file in wheelhouse/audited/*.whl; do + echo "Uploading $file" + python3 -m twine upload --repository-url "$PYPI_SERVER" --username "$PYPI_USER" --password "$PYPI_PASSWORD" "$file" +done + +# Uploads zip source distribution +for file in wheelhouse/audited/*.zip; do + echo "Uploading $file" + python3 -m twine upload --repository-url "$PYPI_SERVER" --username "$PYPI_USER" --password "$PYPI_PASSWORD" "$file" +done + +# Uploads tar.gz source distribution +for file in wheelhouse/audited/*.tar.gz; do + echo "Uploading $file" + python3 -m twine upload --repository-url "$PYPI_SERVER" --username "$PYPI_USER" --password "$PYPI_PASSWORD" "$file" +done \ No newline at end of file diff --git a/bindings/python/cmake/CMakeRC.cmake b/bindings/python/cmake/CMakeRC.cmake new file mode 100644 index 000000000..2095e26c2 --- /dev/null +++ b/bindings/python/cmake/CMakeRC.cmake @@ -0,0 +1,1099 @@ +# This block is executed when generating an intermediate resource file, not when +# running in CMake configure mode +if(_CMRC_GENERATE_MODE) + if (INCBIN_ENABLED) + + string(CONFIGURE [[ + #include + namespace cmrc { namespace @NAMESPACE@ { namespace res_chars { + INCBIN(@SYMBOL@, "@INPUT_FILE@"); + extern const char* const @SYMBOL@_begin = (const char*) g@SYMBOL@Data; + extern const char* const @SYMBOL@_end = (const char*) (g@SYMBOL@Data + g@SYMBOL@Size); + }}} + ]] code) + + else() + + # Read in the digits + file(READ "${INPUT_FILE}" bytes HEX) + # Format each pair into a character literal. Heuristics seem to favor doing + # the conversion in groups of five for fastest conversion + string(REGEX REPLACE "(..)(..)(..)(..)(..)" "'\\\\x\\1','\\\\x\\2','\\\\x\\3','\\\\x\\4','\\\\x\\5'," chars "${bytes}") + # Since we did this in groups, we have some leftovers to clean up + string(LENGTH "${bytes}" n_bytes2) + math(EXPR n_bytes "${n_bytes2} / 2") + math(EXPR remainder "${n_bytes} % 5") # <-- '5' is the grouping count from above + set(cleanup_re "$") + set(cleanup_sub ) + while(remainder) + set(cleanup_re "(..)${cleanup_re}") + set(cleanup_sub "'\\\\x\\${remainder}',${cleanup_sub}") + math(EXPR remainder "${remainder} - 1") + endwhile() + if(NOT cleanup_re STREQUAL "$") + string(REGEX REPLACE "${cleanup_re}" "${cleanup_sub}" chars "${chars}") + endif() + + string(CONFIGURE [[ + namespace { const char file_array[] = { @chars@ 0 }; } + namespace cmrc { namespace @NAMESPACE@ { namespace res_chars { + extern const char* const @SYMBOL@_begin = file_array; + extern const char* const @SYMBOL@_end = file_array + @n_bytes@; + }}} + ]] code) + + endif() + + file(WRITE "${OUTPUT_FILE}" "${code}") + # Exit from the script. Nothing else needs to be processed + return() +endif() + + + +set(_version 2.0.0) + +cmake_minimum_required(VERSION 3.3) +include(CMakeParseArguments) + +if(COMMAND cmrc_add_resource_library) + if(NOT DEFINED _CMRC_VERSION OR NOT (_version STREQUAL _CMRC_VERSION)) + message(WARNING "More than one CMakeRC version has been included in this project.") + endif() + # CMakeRC has already been included! Don't do anything + return() +endif() + +set(_CMRC_VERSION "${_version}" CACHE INTERNAL "CMakeRC version. Used for checking for conflicts") + +set(_CMRC_SCRIPT "${CMAKE_CURRENT_LIST_FILE}" CACHE INTERNAL "Path to CMakeRC script") + +function(_cmrc_normalize_path var) + set(path "${${var}}") + file(TO_CMAKE_PATH "${path}" path) + while(path MATCHES "//") + string(REPLACE "//" "/" path "${path}") + endwhile() + string(REGEX REPLACE "/+$" "" path "${path}") + set("${var}" "${path}" PARENT_SCOPE) +endfunction() + +get_filename_component(_inc_dir "${CMAKE_BINARY_DIR}/_cmrc/include" ABSOLUTE) +set(CMRC_INCLUDE_DIR "${_inc_dir}" CACHE INTERNAL "Directory for CMakeRC include files") +# Let's generate the primary include file +file(MAKE_DIRECTORY "${CMRC_INCLUDE_DIR}/cmrc") +set(hpp_content [==[ +#ifndef CMRC_CMRC_HPP_INCLUDED +#define CMRC_CMRC_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace cmrc { namespace detail { struct dummy; } } + +#define CMRC_DECLARE(libid) \ + namespace cmrc { namespace detail { \ + struct dummy; \ + static_assert(std::is_same::value, "CMRC_DECLARE() must only appear at the global namespace"); \ + } } \ + namespace cmrc { namespace libid { \ + cmrc::embedded_filesystem get_filesystem(); \ + } } static_assert(true, "") + +namespace cmrc { + +class file { + const char* _begin = nullptr; + const char* _end = nullptr; + +public: + using iterator = const char*; + using const_iterator = iterator; + iterator begin() const noexcept { return _begin; } + iterator cbegin() const noexcept { return _begin; } + iterator end() const noexcept { return _end; } + iterator cend() const noexcept { return _end; } + std::size_t size() const { return std::distance(begin(), end()); } + + file() = default; + file(iterator beg, iterator end) noexcept : _begin(beg), _end(end) {} +}; + +class directory_entry; + +namespace detail { + +class directory; +class file_data; + +class file_or_directory { + union _data_t { + class file_data* file_data; + class directory* directory; + } _data; + bool _is_file = true; + +public: + explicit file_or_directory(file_data& f) { + _data.file_data = &f; + } + explicit file_or_directory(directory& d) { + _data.directory = &d; + _is_file = false; + } + bool is_file() const noexcept { + return _is_file; + } + bool is_directory() const noexcept { + return !is_file(); + } + const directory& as_directory() const noexcept { + assert(!is_file()); + return *_data.directory; + } + const file_data& as_file() const noexcept { + assert(is_file()); + return *_data.file_data; + } +}; + +class file_data { +public: + const char* begin_ptr; + const char* end_ptr; + file_data(const file_data&) = delete; + file_data(const char* b, const char* e) : begin_ptr(b), end_ptr(e) {} +}; + +inline std::pair split_path(const std::string& path) { + auto first_sep = path.find("/"); + if (first_sep == path.npos) { + return std::make_pair(path, ""); + } else { + return std::make_pair(path.substr(0, first_sep), path.substr(first_sep + 1)); + } +} + +struct created_subdirectory { + class directory& directory; + class file_or_directory& index_entry; +}; + +class directory { + std::list _files; + std::list _dirs; + std::map _index; + + using base_iterator = std::map::const_iterator; + +public: + + directory() = default; + directory(const directory&) = delete; + + created_subdirectory add_subdir(std::string name) & { + _dirs.emplace_back(); + auto& back = _dirs.back(); + auto& fod = _index.emplace(name, file_or_directory{back}).first->second; + return created_subdirectory{back, fod}; + } + + file_or_directory* add_file(std::string name, const char* begin, const char* end) & { + assert(_index.find(name) == _index.end()); + _files.emplace_back(begin, end); + return &_index.emplace(name, file_or_directory{_files.back()}).first->second; + } + + const file_or_directory* get(const std::string& path) const { + auto pair = split_path(path); + auto child = _index.find(pair.first); + if (child == _index.end()) { + return nullptr; + } + auto& entry = child->second; + if (pair.second.empty()) { + // We're at the end of the path + return &entry; + } + + if (entry.is_file()) { + // We can't traverse into a file. Stop. + return nullptr; + } + // Keep going down + return entry.as_directory().get(pair.second); + } + + class iterator { + base_iterator _base_iter; + base_iterator _end_iter; + public: + using value_type = directory_entry; + using difference_type = std::ptrdiff_t; + using pointer = const value_type*; + using reference = const value_type&; + using iterator_category = std::input_iterator_tag; + + iterator() = default; + explicit iterator(base_iterator iter, base_iterator end) : _base_iter(iter), _end_iter(end) {} + + iterator begin() const noexcept { + return *this; + } + + iterator end() const noexcept { + return iterator(_end_iter, _end_iter); + } + + inline value_type operator*() const noexcept; + + bool operator==(const iterator& rhs) const noexcept { + return _base_iter == rhs._base_iter; + } + + bool operator!=(const iterator& rhs) const noexcept { + return !(*this == rhs); + } + + iterator operator++() noexcept { + auto cp = *this; + ++_base_iter; + return cp; + } + + iterator& operator++(int) noexcept { + ++_base_iter; + return *this; + } + }; + + using const_iterator = iterator; + + iterator begin() const noexcept { + return iterator(_index.begin(), _index.end()); + } + + iterator end() const noexcept { + return iterator(); + } +}; + +inline std::string normalize_path(std::string path) { + while (path.find("/") == 0) { + path.erase(path.begin()); + } + while (!path.empty() && (path.rfind("/") == path.size() - 1)) { + path.pop_back(); + } + auto off = path.npos; + while ((off = path.find("//")) != path.npos) { + path.erase(path.begin() + off); + } + return path; +} + +using index_type = std::map; + +} // detail + +class directory_entry { + std::string _fname; + const detail::file_or_directory* _item; + +public: + directory_entry() = delete; + explicit directory_entry(std::string filename, const detail::file_or_directory& item) + : _fname(filename) + , _item(&item) + {} + + const std::string& filename() const & { + return _fname; + } + std::string filename() const && { + return std::move(_fname); + } + + bool is_file() const { + return _item->is_file(); + } + + bool is_directory() const { + return _item->is_directory(); + } +}; + +directory_entry detail::directory::iterator::operator*() const noexcept { + assert(begin() != end()); + return directory_entry(_base_iter->first, _base_iter->second); +} + +using directory_iterator = detail::directory::iterator; + +class embedded_filesystem { + // Never-null: + const cmrc::detail::index_type* _index; + const detail::file_or_directory* _get(std::string path) const { + path = detail::normalize_path(path); + auto found = _index->find(path); + if (found == _index->end()) { + return nullptr; + } else { + return found->second; + } + } + +public: + explicit embedded_filesystem(const detail::index_type& index) + : _index(&index) + {} + + file open(const std::string& path) const { + auto entry_ptr = _get(path); + if (!entry_ptr || !entry_ptr->is_file()) { + throw std::system_error(make_error_code(std::errc::no_such_file_or_directory), path); + } + auto& dat = entry_ptr->as_file(); + return file{dat.begin_ptr, dat.end_ptr}; + } + + bool is_file(const std::string& path) const noexcept { + auto entry_ptr = _get(path); + return entry_ptr && entry_ptr->is_file(); + } + + bool is_directory(const std::string& path) const noexcept { + auto entry_ptr = _get(path); + return entry_ptr && entry_ptr->is_directory(); + } + + bool exists(const std::string& path) const noexcept { + return !!_get(path); + } + + directory_iterator iterate_directory(const std::string& path) const { + auto entry_ptr = _get(path); + if (!entry_ptr) { + throw std::system_error(make_error_code(std::errc::no_such_file_or_directory), path); + } + if (!entry_ptr->is_directory()) { + throw std::system_error(make_error_code(std::errc::not_a_directory), path); + } + return entry_ptr->as_directory().begin(); + } +}; + +} + +#endif // CMRC_CMRC_HPP_INCLUDED +]==]) + +set(cmrc_hpp "${CMRC_INCLUDE_DIR}/cmrc/cmrc.hpp" CACHE INTERNAL "") +set(_generate 1) +if(EXISTS "${cmrc_hpp}") + file(READ "${cmrc_hpp}" _current) + if(_current STREQUAL hpp_content) + set(_generate 0) + endif() +endif() +file(GENERATE OUTPUT "${cmrc_hpp}" CONTENT "${hpp_content}" CONDITION ${_generate}) + +add_library(cmrc-base INTERFACE) + +# Add interface include for users of library +target_include_directories(cmrc-base SYSTEM INTERFACE "$") + +# Signal a basic C++11 feature to require C++11. +target_compile_features(cmrc-base INTERFACE cxx_nullptr) +set_property(TARGET cmrc-base PROPERTY INTERFACE_CXX_EXTENSIONS OFF) +add_library(cmrc::base ALIAS cmrc-base) + + + +### Incbin project addition, this enables much quicker compile times on supported compilers +# https://github.com/graphitemaster/incbin +# Incbin project +# Commit: 8cefe46d5380bf5ae4b4d87832d811f6692aae44 + +# Create an option to use it (default on, with try_compile checks to make sure it works) +option(CMRC_COMPATIBILITY_MODE "If enabled intermediate character array is generated (Supports all compilers)" OFF) + +set(incbin_h_content [==[ +/** + * @file incbin.h + * @author Dale Weiler + * @brief Utility for including binary files + * + * Facilities for including binary files into the current translation unit and + * making use from them externally in other translation units. + */ +#ifndef INCBIN_HDR +#define INCBIN_HDR +#include +#if defined(__AVX512BW__) || \ + defined(__AVX512CD__) || \ + defined(__AVX512DQ__) || \ + defined(__AVX512ER__) || \ + defined(__AVX512PF__) || \ + defined(__AVX512VL__) || \ + defined(__AVX512F__) +# define INCBIN_ALIGNMENT_INDEX 6 +#elif defined(__AVX__) || \ + defined(__AVX2__) +# define INCBIN_ALIGNMENT_INDEX 5 +#elif defined(__SSE__) || \ + defined(__SSE2__) || \ + defined(__SSE3__) || \ + defined(__SSSE3__) || \ + defined(__SSE4_1__) || \ + defined(__SSE4_2__) || \ + defined(__neon__) +# define INCBIN_ALIGNMENT_INDEX 4 +#elif ULONG_MAX != 0xffffffffu +# define INCBIN_ALIGNMENT_INDEX 3 +# else +# define INCBIN_ALIGNMENT_INDEX 2 +#endif + +/* Lookup table of (1 << n) where `n' is `INCBIN_ALIGNMENT_INDEX' */ +#define INCBIN_ALIGN_SHIFT_0 1 +#define INCBIN_ALIGN_SHIFT_1 2 +#define INCBIN_ALIGN_SHIFT_2 4 +#define INCBIN_ALIGN_SHIFT_3 8 +#define INCBIN_ALIGN_SHIFT_4 16 +#define INCBIN_ALIGN_SHIFT_5 32 +#define INCBIN_ALIGN_SHIFT_6 64 + +/* Actual alignment value */ +#define INCBIN_ALIGNMENT \ + INCBIN_CONCATENATE( \ + INCBIN_CONCATENATE(INCBIN_ALIGN_SHIFT, _), \ + INCBIN_ALIGNMENT_INDEX) + +/* Stringize */ +#define INCBIN_STR(X) \ + #X +#define INCBIN_STRINGIZE(X) \ + INCBIN_STR(X) +/* Concatenate */ +#define INCBIN_CAT(X, Y) \ + X ## Y +#define INCBIN_CONCATENATE(X, Y) \ + INCBIN_CAT(X, Y) +/* Deferred macro expansion */ +#define INCBIN_EVAL(X) \ + X +#define INCBIN_INVOKE(N, ...) \ + INCBIN_EVAL(N(__VA_ARGS__)) + +/* Green Hills uses a different directive for including binary data */ +#if defined(__ghs__) +# if (__ghs_asm == 2) +# define INCBIN_MACRO ".file" +/* Or consider the ".myrawdata" entry in the ld file */ +# else +# define INCBIN_MACRO "\tINCBIN" +# endif +#else +# define INCBIN_MACRO ".incbin" +#endif + +#ifndef _MSC_VER +# define INCBIN_ALIGN \ + __attribute__((aligned(INCBIN_ALIGNMENT))) +#else +# define INCBIN_ALIGN __declspec(align(INCBIN_ALIGNMENT)) +#endif + +#if defined(__arm__) || /* GNU C and RealView */ \ + defined(__arm) || /* Diab */ \ + defined(_ARM) /* ImageCraft */ +# define INCBIN_ARM +#endif + +#ifdef __GNUC__ +/* Utilize .balign where supported */ +# define INCBIN_ALIGN_HOST ".balign " INCBIN_STRINGIZE(INCBIN_ALIGNMENT) "\n" +# define INCBIN_ALIGN_BYTE ".balign 1\n" +#elif defined(INCBIN_ARM) +/* + * On arm assemblers, the alignment value is calculated as (1 << n) where `n' is + * the shift count. This is the value passed to `.align' + */ +# define INCBIN_ALIGN_HOST ".align " INCBIN_STRINGIZE(INCBIN_ALIGNMENT_INDEX) "\n" +# define INCBIN_ALIGN_BYTE ".align 0\n" +#else +/* We assume other inline assembler's treat `.align' as `.balign' */ +# define INCBIN_ALIGN_HOST ".align " INCBIN_STRINGIZE(INCBIN_ALIGNMENT) "\n" +# define INCBIN_ALIGN_BYTE ".align 1\n" +#endif + +/* INCBIN_CONST is used by incbin.c generated files */ +#if defined(__cplusplus) +# define INCBIN_EXTERNAL extern "C" +# define INCBIN_CONST extern const +#else +# define INCBIN_EXTERNAL extern +# define INCBIN_CONST const +#endif + +/** + * @brief Optionally override the linker section into which data is emitted. + * + * @warning If you use this facility, you'll have to deal with platform-specific linker output + * section naming on your own + * + * Overriding the default linker output section, e.g for esp8266/Arduino: + * @code + * #define INCBIN_OUTPUT_SECTION ".irom.text" + * #include "incbin.h" + * INCBIN(Foo, "foo.txt"); + * // Data is emitted into program memory that never gets copied to RAM + * @endcode + */ +#if !defined(INCBIN_OUTPUT_SECTION) +# if defined(__APPLE__) +# define INCBIN_OUTPUT_SECTION ".const_data" +# else +# define INCBIN_OUTPUT_SECTION ".rodata" +# endif +#endif + +#if defined(__APPLE__) +/* The directives are different for Apple branded compilers */ +# define INCBIN_SECTION INCBIN_OUTPUT_SECTION "\n" +# define INCBIN_GLOBAL(NAME) ".globl " INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME "\n" +# define INCBIN_INT ".long " +# define INCBIN_MANGLE "_" +# define INCBIN_BYTE ".byte " +# define INCBIN_TYPE(...) +#else +# define INCBIN_SECTION ".section " INCBIN_OUTPUT_SECTION "\n" +# define INCBIN_GLOBAL(NAME) ".global " INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME "\n" +# if defined(__ghs__) +# define INCBIN_INT ".word " +# else +# define INCBIN_INT ".int " +# endif +# if defined(__USER_LABEL_PREFIX__) +# define INCBIN_MANGLE INCBIN_STRINGIZE(__USER_LABEL_PREFIX__) +# else +# define INCBIN_MANGLE "" +# endif +# if defined(INCBIN_ARM) +/* On arm assemblers, `@' is used as a line comment token */ +# define INCBIN_TYPE(NAME) ".type " INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME ", %object\n" +# elif defined(__MINGW32__) || defined(__MINGW64__) +/* Mingw doesn't support this directive either */ +# define INCBIN_TYPE(NAME) +# else +/* It's safe to use `@' on other architectures */ +# define INCBIN_TYPE(NAME) ".type " INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME ", @object\n" +# endif +# define INCBIN_BYTE ".byte " +#endif + +/* List of style types used for symbol names */ +#define INCBIN_STYLE_CAMEL 0 +#define INCBIN_STYLE_SNAKE 1 + +/** + * @brief Specify the prefix to use for symbol names. + * + * By default this is `g', producing symbols of the form: + * @code + * #include "incbin.h" + * INCBIN(Foo, "foo.txt"); + * + * // Now you have the following symbols: + * // const unsigned char gFooData[]; + * // const unsigned char *const gFooEnd; + * // const unsigned int gFooSize; + * @endcode + * + * If however you specify a prefix before including: e.g: + * @code + * #define INCBIN_PREFIX incbin + * #include "incbin.h" + * INCBIN(Foo, "foo.txt"); + * + * // Now you have the following symbols instead: + * // const unsigned char incbinFooData[]; + * // const unsigned char *const incbinFooEnd; + * // const unsigned int incbinFooSize; + * @endcode + */ +#if !defined(INCBIN_PREFIX) +# define INCBIN_PREFIX g +#endif + +/** + * @brief Specify the style used for symbol names. + * + * Possible options are + * - INCBIN_STYLE_CAMEL "CamelCase" + * - INCBIN_STYLE_SNAKE "snake_case" + * + * Default option is *INCBIN_STYLE_CAMEL* producing symbols of the form: + * @code + * #include "incbin.h" + * INCBIN(Foo, "foo.txt"); + * + * // Now you have the following symbols: + * // const unsigned char FooData[]; + * // const unsigned char *const FooEnd; + * // const unsigned int FooSize; + * @endcode + * + * If however you specify a style before including: e.g: + * @code + * #define INCBIN_STYLE INCBIN_STYLE_SNAKE + * #include "incbin.h" + * INCBIN(foo, "foo.txt"); + * + * // Now you have the following symbols: + * // const unsigned char foo_data[]; + * // const unsigned char *const foo_end; + * // const unsigned int foo_size; + * @endcode + */ +#if !defined(INCBIN_STYLE) +# define INCBIN_STYLE INCBIN_STYLE_CAMEL +#endif + +/* Style lookup tables */ +#define INCBIN_STYLE_0_DATA Data +#define INCBIN_STYLE_0_END End +#define INCBIN_STYLE_0_SIZE Size +#define INCBIN_STYLE_1_DATA _data +#define INCBIN_STYLE_1_END _end +#define INCBIN_STYLE_1_SIZE _size + +/* Style lookup: returning identifier */ +#define INCBIN_STYLE_IDENT(TYPE) \ + INCBIN_CONCATENATE( \ + INCBIN_STYLE_, \ + INCBIN_CONCATENATE( \ + INCBIN_EVAL(INCBIN_STYLE), \ + INCBIN_CONCATENATE(_, TYPE))) + +/* Style lookup: returning string literal */ +#define INCBIN_STYLE_STRING(TYPE) \ + INCBIN_STRINGIZE( \ + INCBIN_STYLE_IDENT(TYPE)) \ + +/* Generate the global labels by indirectly invoking the macro with our style + * type and concatenating the name against them. */ +#define INCBIN_GLOBAL_LABELS(NAME, TYPE) \ + INCBIN_INVOKE( \ + INCBIN_GLOBAL, \ + INCBIN_CONCATENATE( \ + NAME, \ + INCBIN_INVOKE( \ + INCBIN_STYLE_IDENT, \ + TYPE))) \ + INCBIN_INVOKE( \ + INCBIN_TYPE, \ + INCBIN_CONCATENATE( \ + NAME, \ + INCBIN_INVOKE( \ + INCBIN_STYLE_IDENT, \ + TYPE))) + +/** + * @brief Externally reference binary data included in another translation unit. + * + * Produces three external symbols that reference the binary data included in + * another translation unit. + * + * The symbol names are a concatenation of `INCBIN_PREFIX' before *NAME*; with + * "Data", as well as "End" and "Size" after. An example is provided below. + * + * @param NAME The name given for the binary data + * + * @code + * INCBIN_EXTERN(Foo); + * + * // Now you have the following symbols: + * // extern const unsigned char FooData[]; + * // extern const unsigned char *const FooEnd; + * // extern const unsigned int FooSize; + * @endcode + */ +#define INCBIN_EXTERN(NAME) \ + INCBIN_EXTERNAL const INCBIN_ALIGN unsigned char \ + INCBIN_CONCATENATE( \ + INCBIN_CONCATENATE(INCBIN_PREFIX, NAME), \ + INCBIN_STYLE_IDENT(DATA))[]; \ + INCBIN_EXTERNAL const INCBIN_ALIGN unsigned char *const \ + INCBIN_CONCATENATE( \ + INCBIN_CONCATENATE(INCBIN_PREFIX, NAME), \ + INCBIN_STYLE_IDENT(END)); \ + INCBIN_EXTERNAL const unsigned int \ + INCBIN_CONCATENATE( \ + INCBIN_CONCATENATE(INCBIN_PREFIX, NAME), \ + INCBIN_STYLE_IDENT(SIZE)) + +/** + * @brief Include a binary file into the current translation unit. + * + * Includes a binary file into the current translation unit, producing three symbols + * for objects that encode the data and size respectively. + * + * The symbol names are a concatenation of `INCBIN_PREFIX' before *NAME*; with + * "Data", as well as "End" and "Size" after. An example is provided below. + * + * @param NAME The name to associate with this binary data (as an identifier.) + * @param FILENAME The file to include (as a string literal.) + * + * @code + * INCBIN(Icon, "icon.png"); + * + * // Now you have the following symbols: + * // const unsigned char IconData[]; + * // const unsigned char *const IconEnd; + * // const unsigned int IconSize; + * @endcode + * + * @warning This must be used in global scope + * @warning The identifiers may be different if INCBIN_STYLE is not default + * + * To externally reference the data included by this in another translation unit + * please @see INCBIN_EXTERN. + */ +#ifdef _MSC_VER +#define INCBIN(NAME, FILENAME) \ + INCBIN_EXTERN(NAME) +#else +#define INCBIN(NAME, FILENAME) \ + __asm__(INCBIN_SECTION \ + INCBIN_GLOBAL_LABELS(NAME, DATA) \ + INCBIN_ALIGN_HOST \ + INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME INCBIN_STYLE_STRING(DATA) ":\n" \ + INCBIN_MACRO " \"" FILENAME "\"\n" \ + INCBIN_GLOBAL_LABELS(NAME, END) \ + INCBIN_ALIGN_BYTE \ + INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME INCBIN_STYLE_STRING(END) ":\n" \ + INCBIN_BYTE "1\n" \ + INCBIN_GLOBAL_LABELS(NAME, SIZE) \ + INCBIN_ALIGN_HOST \ + INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME INCBIN_STYLE_STRING(SIZE) ":\n" \ + INCBIN_INT INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME INCBIN_STYLE_STRING(END) " - " \ + INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME INCBIN_STYLE_STRING(DATA) "\n" \ + INCBIN_ALIGN_HOST \ + ".text\n" \ + ); \ + INCBIN_EXTERN(NAME) + +#endif +#endif +]==]) + +if (CMRC_COMPATIBILITY_MODE) + set(HAVE_INCBIN_CAPABILITY FALSE CACHE INTERNAL "") +else() + + get_filename_component(_inc_gen_dir "${CMAKE_BINARY_DIR}/_cmrc/gen/include" ABSOLUTE) + # Lets generate incbin.h file + file(MAKE_DIRECTORY "${_inc_gen_dir}/incbin") + + + # Create in generate stage + set(cmrc_incbin_h "${_inc_gen_dir}/incbin/incbin.h" CACHE INTERNAL "") + set(_incbin_generate 1) + if(EXISTS "${cmrc_incbin_h}") + file(READ "${cmrc_incbin_h}" _incbin_current) + if(_incbin_current STREQUAL incbin_h_content) + set(_incbin_generate 0) + endif() + endif() + file(GENERATE OUTPUT "${cmrc_incbin_h}" CONTENT "${incbin_h_content}" CONDITION ${_incbin_generate}) + + # Tests if incbin assembly directive works for current compiler (otherwise fallback to generating character array) + + if(NOT CMRC_INCBIN_TESTS_DONE) + + # Let's generate the test for incbin.h + get_filename_component(_tests_gen_dir "${CMAKE_BINARY_DIR}/_cmrc/tests" ABSOLUTE) + file(MAKE_DIRECTORY "${_tests_gen_dir}") + + # Create a sample input file + set(test_txt_content [==[ + Hello World! + ]==]) + file(WRITE "${_tests_gen_dir}/test.txt" "${test_txt_content}") + + # Create a test program source + string(CONFIGURE [==[ + #define INCBIN_PREFIX g_ + #define INCBIN_STYLE INCBIN_STYLE_SNAKE + @incbin_h_content@ + namespace test{ + INCBIN(test, "@_tests_gen_dir@/test.txt"); + } + int main(){ + int sum = 0; + for(unsigned int i = 0; i + #include + #include + + namespace cmrc { + namespace @ARG_NAMESPACE@ { + + namespace res_chars { + // These are the files which are available in this resource library + $, + > + } + + namespace { + + const cmrc::detail::index_type& + get_root_index() { + static cmrc::detail::directory root_directory_; + static cmrc::detail::file_or_directory root_directory_fod{root_directory_}; + static cmrc::detail::index_type root_index; + root_index.emplace("", &root_directory_fod); + struct dir_inl { + class cmrc::detail::directory& directory; + }; + dir_inl root_directory_dir{root_directory_}; + (void)root_directory_dir; + $, + > + $, + > + return root_index; + } + + } + + cmrc::embedded_filesystem get_filesystem() { + static auto& index = get_root_index(); + return cmrc::embedded_filesystem{index}; + } + + } // @ARG_NAMESPACE@ + } // cmrc + ]=] cpp_content @ONLY) + get_filename_component(libdir "${CMAKE_CURRENT_BINARY_DIR}/__cmrc_${name}" ABSOLUTE) + get_filename_component(lib_tmp_cpp "${libdir}/lib_.cpp" ABSOLUTE) + string(REPLACE "\n " "\n" cpp_content "${cpp_content}") + file(GENERATE OUTPUT "${lib_tmp_cpp}" CONTENT "${cpp_content}") + get_filename_component(libcpp "${libdir}/lib.cpp" ABSOLUTE) + add_custom_command(OUTPUT "${libcpp}" + DEPENDS "${lib_tmp_cpp}" "${cmrc_hpp}" + COMMAND ${CMAKE_COMMAND} -E copy_if_different "${lib_tmp_cpp}" "${libcpp}" + COMMENT "Generating ${name} resource loader" + ) + # Generate the actual static library. Each source file is just a single file + # with a character array compiled in containing the contents of the + # corresponding resource file. + add_library(${name} STATIC ${libcpp}) + + # Add private include to incbin/incbin.h + target_include_directories(${name} PRIVATE "${_inc_gen_dir}") + + set_property(TARGET ${name} PROPERTY CMRC_LIBDIR "${libdir}") + set_property(TARGET ${name} PROPERTY CMRC_NAMESPACE "${ARG_NAMESPACE}") + target_link_libraries(${name} PUBLIC cmrc::base) + set_property(TARGET ${name} PROPERTY CMRC_IS_RESOURCE_LIBRARY TRUE) + if(ARG_ALIAS) + add_library("${ARG_ALIAS}" ALIAS ${name}) + endif() + cmrc_add_resources(${name} ${ARG_UNPARSED_ARGUMENTS}) +endfunction() + +function(_cmrc_register_dirs name dirpath) + if(dirpath STREQUAL "") + return() + endif() + # Skip this dir if we have already registered it + get_target_property(registered "${name}" _CMRC_REGISTERED_DIRS) + if(dirpath IN_LIST registered) + return() + endif() + # Register the parent directory first + get_filename_component(parent "${dirpath}" DIRECTORY) + if(NOT parent STREQUAL "") + _cmrc_register_dirs("${name}" "${parent}") + endif() + # Now generate the registration + set_property(TARGET "${name}" APPEND PROPERTY _CMRC_REGISTERED_DIRS "${dirpath}") + _cm_encode_fpath(sym "${dirpath}") + if(parent STREQUAL "") + set(parent_sym root_directory) + else() + _cm_encode_fpath(parent_sym "${parent}") + endif() + get_filename_component(leaf "${dirpath}" NAME) + set_property( + TARGET "${name}" + APPEND PROPERTY CMRC_MAKE_DIRS + "static auto ${sym}_dir = ${parent_sym}_dir.directory.add_subdir(\"${leaf}\")\;" + "root_index.emplace(\"${dirpath}\", &${sym}_dir.index_entry)\;" + ) +endfunction() + +function(cmrc_add_resources name) + get_target_property(is_reslib ${name} CMRC_IS_RESOURCE_LIBRARY) + if(NOT TARGET ${name} OR NOT is_reslib) + message(SEND_ERROR "cmrc_add_resources called on target '${name}' which is not an existing resource library") + return() + endif() + + set(options) + set(args WHENCE PREFIX) + set(list_args) + cmake_parse_arguments(ARG "${options}" "${args}" "${list_args}" "${ARGN}") + + if(NOT ARG_WHENCE) + set(ARG_WHENCE ${CMAKE_CURRENT_SOURCE_DIR}) + endif() + _cmrc_normalize_path(ARG_WHENCE) + get_filename_component(ARG_WHENCE "${ARG_WHENCE}" ABSOLUTE) + + # Generate the identifier for the resource library's namespace + get_target_property(lib_ns "${name}" CMRC_NAMESPACE) + + get_target_property(libdir ${name} CMRC_LIBDIR) + get_target_property(target_dir ${name} SOURCE_DIR) + file(RELATIVE_PATH reldir "${target_dir}" "${CMAKE_CURRENT_SOURCE_DIR}") + if(reldir MATCHES "^\\.\\.") + message(SEND_ERROR "Cannot call cmrc_add_resources in a parent directory from the resource library target") + return() + endif() + + foreach(input IN LISTS ARG_UNPARSED_ARGUMENTS) + _cmrc_normalize_path(input) + get_filename_component(abs_in "${input}" ABSOLUTE) + # Generate a filename based on the input filename that we can put in + # the intermediate directory. + file(RELATIVE_PATH relpath "${ARG_WHENCE}" "${abs_in}") + if(relpath MATCHES "^\\.\\.") + # For now we just error on files that exist outside of the soure dir. + message(SEND_ERROR "Cannot add file '${input}': File must be in a subdirectory of ${ARG_WHENCE}") + continue() + endif() + if(DEFINED ARG_PREFIX) + _cmrc_normalize_path(ARG_PREFIX) + endif() + if(ARG_PREFIX AND NOT ARG_PREFIX MATCHES "/$") + set(ARG_PREFIX "${ARG_PREFIX}/") + endif() + get_filename_component(dirpath "${ARG_PREFIX}${relpath}" DIRECTORY) + _cmrc_register_dirs("${name}" "${dirpath}") + get_filename_component(abs_out "${libdir}/intermediate/${relpath}.cpp" ABSOLUTE) + # Generate a symbol name relpath the file's character array + _cm_encode_fpath(sym "${relpath}") + # Get the symbol name for the parent directory + if(dirpath STREQUAL "") + set(parent_sym root_directory) + else() + _cm_encode_fpath(parent_sym "${dirpath}") + endif() + # Generate the rule for the intermediate source file + _cmrc_generate_intermediate_cpp(${lib_ns} ${sym} "${abs_out}" "${abs_in}" "${HAVE_INCBIN_CAPABILITY}") + target_sources(${name} PRIVATE "${abs_out}") + set_property(TARGET ${name} APPEND PROPERTY CMRC_EXTERN_DECLS + "// Pointers to ${input}" + "extern const char* const ${sym}_begin\;" + "extern const char* const ${sym}_end\;" + ) + get_filename_component(leaf "${relpath}" NAME) + set_property( + TARGET ${name} + APPEND PROPERTY CMRC_MAKE_FILES + "root_index.emplace(" + " \"${ARG_PREFIX}${relpath}\"," + " ${parent_sym}_dir.directory.add_file(" + " \"${leaf}\"," + " res_chars::${sym}_begin," + " res_chars::${sym}_end" + " )" + ")\;" + ) + endforeach() +endfunction() + +function(_cmrc_generate_intermediate_cpp lib_ns symbol outfile infile incbin_enabled) + add_custom_command( + # This is the file we will generate + OUTPUT "${outfile}" + # These are the primary files that affect the output + DEPENDS "${infile}" "${_CMRC_SCRIPT}" + COMMAND + "${CMAKE_COMMAND}" + -D_CMRC_GENERATE_MODE=TRUE + -DNAMESPACE=${lib_ns} + -DSYMBOL=${symbol} + "-DINPUT_FILE=${infile}" + "-DOUTPUT_FILE=${outfile}" + "-DINCBIN_ENABLED=${incbin_enabled}" + -P "${_CMRC_SCRIPT}" + COMMENT "Generating intermediate file for ${infile}" + ) +endfunction() + +function(_cm_encode_fpath var fpath) + string(MAKE_C_IDENTIFIER "${fpath}" ident) + string(MD5 hash "${fpath}") + string(SUBSTRING "${hash}" 0 4 hash) + set(${var} f_${hash}_${ident} PARENT_SCOPE) +endfunction() diff --git a/bindings/python/cmake/ClangFormat.cmake b/bindings/python/cmake/ClangFormat.cmake new file mode 100644 index 000000000..cbdc3baec --- /dev/null +++ b/bindings/python/cmake/ClangFormat.cmake @@ -0,0 +1,67 @@ +# Copyright Tomas Zeman 2019. +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +function(clangformat_setup files target) + + if(NOT CLANG_FORMAT_BIN) + set(CLANG_FORMAT_BIN clang-format) + endif() + + if(NOT EXISTS ${CLANG_FORMAT_BIN}) + find_program(CLANG_FORMAT_BIN_tmp NAMES clang-format clang-format-10 clang-format-11 clang-format-12 clang-format-13 clang-format-14) + if(CLANG_FORMAT_BIN_tmp) + set(CLANG_FORMAT_BIN ${CLANG_FORMAT_BIN_tmp}) + unset(CLANG_FORMAT_BIN_tmp) + else() + message(STATUS "ClangFormat: ${CLANG_FORMAT_BIN} not found! Target 'clangformat' not available...") + return() + endif() + endif() + + foreach(clangformat_source ${files}) + get_filename_component(clangformat_source ${clangformat_source} ABSOLUTE) + list(APPEND clangformat_sources ${clangformat_source}) + endforeach() + + add_custom_target(${target}_clangformat + COMMAND + ${CLANG_FORMAT_BIN} + -style=file + -i + ${clangformat_sources} + WORKING_DIRECTORY + ${CMAKE_SOURCE_DIR} + COMMENT + "Formating with ${CLANG_FORMAT_BIN} ..." + ) + + if(TARGET clangformat) + add_dependencies(clangformat ${target}_clangformat) + else() + add_custom_target(clangformat DEPENDS ${target}_clangformat) + endif() +endfunction() + + +macro(header_directories header_dirs return_list) + + foreach(header_dir ${header_dirs}) + file(GLOB_RECURSE new_list "${header_dir}/*.hpp") + set(file_list "") + foreach(file_path ${new_list}) + set(file_list "${file_list}" ${file_path}) + endforeach() + list(REMOVE_DUPLICATES file_list) + set(${return_list} "${${return_list}}" "${file_list}") + endforeach() + +endmacro() + +function(target_clangformat_setup target header_dirs) + get_target_property(target_sources ${target} SOURCES) + header_directories("${header_dirs}" header_files) + set(target_files_to_format "${target_sources};${header_files}") + clangformat_setup("${target_files_to_format}" ${target}) +endfunction() diff --git a/bindings/python/cmake/ClangTidy.cmake b/bindings/python/cmake/ClangTidy.cmake new file mode 100644 index 000000000..27b7e1959 --- /dev/null +++ b/bindings/python/cmake/ClangTidy.cmake @@ -0,0 +1,21 @@ +function(target_clangtidy_setup target) + + set(CLANG_TIDY_NAMES clang-tidy clang-tidy-10 clang-tidy-11) + foreach(clangtidy ${CLANG_TIDY_NAMES}) + if(CLANG_TIDY_BIN) + break() + endif() + find_program(CLANG_TIDY_BIN ${clangtidy}) + endforeach() + + if(NOT CLANG_TIDY_BIN) + message(FATAL_ERROR "clang-tidy is not installed. Aborting...") + else() + message(STATUS "clang-tidy has been found: ${CLANG_TIDY_BIN}") + endif() + + # Disable for C compiler for now + #set_target_properties(${target} PROPERTIES C_CLANG_TIDY ${CLANG_TIDY_BIN} CXX_CLANG_TIDY ${CLANG_TIDY_BIN}) + set_target_properties(${target} PROPERTIES CXX_CLANG_TIDY ${CLANG_TIDY_BIN}) + +endfunction() \ No newline at end of file diff --git a/bindings/python/cmake/Depthai/DepthaiBootloaderConfig.cmake b/bindings/python/cmake/Depthai/DepthaiBootloaderConfig.cmake new file mode 100644 index 000000000..b8c9e058d --- /dev/null +++ b/bindings/python/cmake/Depthai/DepthaiBootloaderConfig.cmake @@ -0,0 +1,7 @@ +# Maturity level "snapshot" / "release" +set(DEPTHAI_BOOTLOADER_MATURITY "release") +# set(DEPTHAI_BOOTLOADER_MATURITY "snapshot") + +# "version if applicable" +set(DEPTHAI_BOOTLOADER_VERSION "0.0.26") +# set(DEPTHAI_BOOTLOADER_VERSION "0.0.24+57c26493754e2f00e57f6594b0b1a317f762d5f2") diff --git a/bindings/python/cmake/Depthai/DepthaiDeviceKbConfig.cmake b/bindings/python/cmake/Depthai/DepthaiDeviceKbConfig.cmake new file mode 100644 index 000000000..f42f41449 --- /dev/null +++ b/bindings/python/cmake/Depthai/DepthaiDeviceKbConfig.cmake @@ -0,0 +1,7 @@ +# Maturity level "snapshot" / "release" +# set(DEPTHAI_DEVICE_KB_MATURITY "release") +set(DEPTHAI_DEVICE_KB_MATURITY "snapshot") + +# "version if applicable" +# set(DEPTHAI_DEVICE_RVC3_VERSION "0.0.1+93f7b75a885aa32f44c5e9f53b74470c49d2b1af") +set(DEPTHAI_DEVICE_RVC3_VERSION "0.0.1+a0d016ba4b78a61f0e0eff27facbe169be8f62ff") diff --git a/bindings/python/cmake/Depthai/DepthaiDeviceSideConfig.cmake b/bindings/python/cmake/Depthai/DepthaiDeviceSideConfig.cmake new file mode 100644 index 000000000..f51afbd37 --- /dev/null +++ b/bindings/python/cmake/Depthai/DepthaiDeviceSideConfig.cmake @@ -0,0 +1,8 @@ +# Maturity level "snapshot" / "release" +set(DEPTHAI_DEVICE_SIDE_MATURITY "snapshot") + +# "full commit hash of device side binary" +set(DEPTHAI_DEVICE_SIDE_COMMIT "f2d516f0b909aed9d6abd8fa4c429bebafb5ded3") + +# "version if applicable" +set(DEPTHAI_DEVICE_SIDE_VERSION "") diff --git a/bindings/python/cmake/DepthaiBootloaderDownloader.cmake b/bindings/python/cmake/DepthaiBootloaderDownloader.cmake new file mode 100644 index 000000000..5d1540159 --- /dev/null +++ b/bindings/python/cmake/DepthaiBootloaderDownloader.cmake @@ -0,0 +1,208 @@ +# This script downloads depthai device side artifacts + +function(DepthaiBootloaderDownload) + + ### VARIABLES + # Artifactory + set(DOWNLOADER_BASE_URL "https://artifacts.luxonis.com/artifactory") + + # Repositories + set(DOWNLOADER_REPO_SNAPSHOT "luxonis-myriad-snapshot-local") + set(DOWNLOADER_REPO_RELEASE "luxonis-myriad-release-local") + + # Prefix + set(DOWNLOADER_ARTIFACT_PREFIX "depthai-bootloader") + + # Errors and retry count + set(DOWNLOADER_TIMEOUT_S 300) + set(DOWNLOADER_INACTIVE_TIMEOUT_S 60) + set(DOWNLOADER_RETRY_NUM 5) + ### END VARIABLES + + + # PARSE ARGUMENTS + set(_depthai_bootloader_shared_commit ${ARGV0}) + set(_enforce_depthai_bootloader_shared_commit ${ARGV1}) + set(folder "${ARGV2}") + set(output_list_var "${ARGV3}") + set(maturity "${ARGV4}") + set(commit_version_arg "${ARGV5}") + + message(STATUS "Downloading depthai bootloader") + + # END PARSE ARGUMENTS + + #DEBUG + message(STATUS "folder: ${folder}") + message(STATUS "maturity: ${maturity}") + message(STATUS "commit_version_arg: ${commit_version_arg}") + + string(TOLOWER "${maturity}" maturity_lower) + + # Switch between maturity + if("${maturity_lower}" STREQUAL "snapshot") + set(_selected_repo "${DOWNLOADER_REPO_SNAPSHOT}") + set(commit ${commit_version_arg}) + + # Create download directory string + string(CONFIGURE "@DOWNLOADER_BASE_URL@/@DOWNLOADER_REPO_SNAPSHOT@/@DOWNLOADER_ARTIFACT_PREFIX@/@commit@" _download_directory_url) + + # Create _version_commit_identifier + set(_version_commit_identifier "${commit}") + + elseif(${maturity_lower} STREQUAL "release") + set(_selected_repo "${DOWNLOADER_REPO_RELEASE}") + set(version ${commit_version_arg}) + + # Create download directory string + string(CONFIGURE "@DOWNLOADER_BASE_URL@/@DOWNLOADER_REPO_RELEASE@/@DOWNLOADER_ARTIFACT_PREFIX@/@version@" _download_directory_url) + + # Create _version_commit_identifier + set(_version_commit_identifier "${version}") + else() + # Not a recognized maturity level + message(FATAL_ERROR "Cannot download depthai-bootloader binaries. Maturity level not recognized (${maturity_lower})") + return() + endif() + + # Prints error message + macro(PrintErrorMessage status) + if(${status} EQUAL 22) + message(STATUS "Resource not found, check if commit hash is correctly specified.\n") + elseif(${status} EQUAL 28) + message(STATUS "Timeout.\n") + elseif(${status} EQUAL 99) + message(STATUS "Couldn't retrieve files correctly, checksum mismatch.") + else() + message(STATUS "Unknown error.\n") + endif() + endmacro() + + # Download files + function(DownloadAndChecksum url url_checksum output status_var) + + # Check if file already downloaded (in resources) + if(EXISTS "${output}") + get_filename_component(_filename "${output}" NAME) + message(STATUS "File already downloaded (resources): ${_filename}") + set("${status_var}" "0" PARENT_SCOPE) + return() + endif() + + # Retry again if failed + set(_num_retries_left ${DOWNLOADER_RETRY_NUM}) + # Set error by default + set("${status_var}" "1" PARENT_SCOPE) + + while(NOT ${_num_retries_left} EQUAL 0) + math(EXPR _num_retries_left "${_num_retries_left} - 1") + + # Download checksum first + file(DOWNLOAD "${url_checksum}" "${output}.checksum" STATUS _status TIMEOUT ${DOWNLOADER_TIMEOUT_S}) + # Read checksum to file + file(READ "${output}.checksum" _file_checksum) + string(REGEX REPLACE "\n$" "" _file_checksum "${_file_checksum}") + # Remove checksum file + file(REMOVE "${output}.checksum") + #CHECKS + list(GET _status 0 _status_num) + if(${_status_num}) + message(STATUS "Status error: ${_status}") + set("${status_var}" "${_status_num}" PARENT_SCOPE) + continue() + endif() + + + # Download file and validate checksum + file(DOWNLOAD "${url}" "${output}" INACTIVITY_TIMEOUT ${DOWNLOADER_INACTIVE_TIMEOUT_S} STATUS _status TIMEOUT ${DOWNLOADER_TIMEOUT_S} SHOW_PROGRESS) + + #CHECKS + list(GET _status 0 _status_num) + if(${_status_num}) + message(STATUS "Status error: ${_status}") + set("${status_var}" "${_status_num}" PARENT_SCOPE) + continue() + endif() + + # Now check if hash matches (if both files were downloaded without timeouts) + file(SHA256 ${output} _downloaded_checksum) + + # if hashes don't match + if(NOT (_downloaded_checksum STREQUAL _file_checksum)) + message(STATUS "Downloaded file checksum mismatch: ${_downloaded_checksum} != {_file_checksum}") + set("${status_var}" "99" PARENT_SCOPE) + continue() + endif() + + # If no errors happened, set status to 0 + set("${status_var}" "0" PARENT_SCOPE) + # And break the loop + break() + + endwhile() + + endfunction() + + + # Check if depthai-bootloader-shared matches + if(_depthai_bootloader_shared_commit) + message(STATUS "bootloader shared commit: ${_depthai_bootloader_shared_commit}") + DownloadAndChecksum( + "${_download_directory_url}/depthai-bootloader-shared-commit-hash-${_version_commit_identifier}.txt" # File + "${_download_directory_url}/depthai-bootloader-shared-commit-hash-${_version_commit_identifier}.txt.sha256" # File checksum + "${folder}/depthai-bootloader-shared-commit-hash-${_version_commit_identifier}.txt" + status + ) + if(${status}) + + message(STATUS "Couldn't check if depthai-bootloader-shared codebase matches between device and host") + if(${_enforce_depthai_bootloader_shared_commit}) + message(FATAL_ERROR "Aborting.\n") + endif() + + else() + + set(_message_mode WARNING) + if(${_enforce_depthai_bootloader_shared_commit}) + set(_message_mode FATAL_ERROR) + endif() + + # Read commit hash file + file(READ "${folder}/depthai-bootloader-shared-commit-hash-${_version_commit_identifier}.txt" _device_depthai_bootloader_shared_commit_hash) + string(REGEX REPLACE "\n$" "" _device_depthai_bootloader_shared_commit_hash "${_device_depthai_bootloader_shared_commit_hash}") + string(REGEX REPLACE "\n$" "" _depthai_bootloader_shared_commit "${_depthai_bootloader_shared_commit}") + string(COMPARE EQUAL "${_device_depthai_bootloader_shared_commit_hash}" "${_depthai_bootloader_shared_commit}" _is_same) + + # If commits dont match + if(NOT ${_is_same}) + message(${_message_mode} "depthai-bootloader-shared codebases differ between device and host. Enforce (CI): ${_enforce_depthai_bootloader_shared_commit} (device: ${_device_depthai_bootloader_shared_commit_hash}, host: ${_depthai_bootloader_shared_commit}") + else() + message(STATUS "depthai-bootloader-shared between device and host MATCH!. (device: ${_device_depthai_bootloader_shared_commit_hash}, host: ${_depthai_bootloader_shared_commit}") + endif() + + endif() + + endif() + + + # Download depthai-bootloader firmware package + message(STATUS "Downloading and checking depthai-bootloader-fwp.tar.xz") + DownloadAndChecksum( + "${_download_directory_url}/depthai-bootloader-fwp-${_version_commit_identifier}.tar.xz" # File + "${_download_directory_url}/depthai-bootloader-fwp-${_version_commit_identifier}.tar.xz.sha256" # File checksum + "${folder}/depthai-bootloader-fwp-${_version_commit_identifier}.tar.xz" + status + ) + if(${status}) + message(STATUS "\nCouldn't download depthai-bootloader-fwp.tar.xz\n") + PrintErrorMessage(${status}) + message(FATAL_ERROR "Aborting.\n") + endif() + # add depthai-bootloader-fwp.tar.xz to list + list(APPEND "${output_list_var}" "${folder}/depthai-bootloader-fwp-${_version_commit_identifier}.tar.xz") + + + # Set list of files as output + set("${output_list_var}" "${${output_list_var}}" PARENT_SCOPE) + +endfunction() diff --git a/bindings/python/cmake/DepthaiDeviceKbDownloader.cmake b/bindings/python/cmake/DepthaiDeviceKbDownloader.cmake new file mode 100644 index 000000000..efb101b91 --- /dev/null +++ b/bindings/python/cmake/DepthaiDeviceKbDownloader.cmake @@ -0,0 +1,208 @@ +# This script downloads depthai device side artifacts + +function(DepthaiDeviceKbDownload) + + ### VARIABLES + # Artifactory + set(DOWNLOADER_BASE_URL "https://artifacts.luxonis.com/artifactory") + + # Repositories + set(DOWNLOADER_REPO_SNAPSHOT "luxonis-keembay-snapshot-local") + set(DOWNLOADER_REPO_RELEASE "luxonis-keembay-release-local") + + # Prefix + set(DOWNLOADER_ARTIFACT_PREFIX "depthai-device-kb") + + # Errors and retry count + set(DOWNLOADER_TIMEOUT_S 300) + set(DOWNLOADER_INACTIVE_TIMEOUT_S 60) + set(DOWNLOADER_RETRY_NUM 5) + ### END VARIABLES + + + # PARSE ARGUMENTS + set(_depthai_shared_commit ${ARGV0}) + set(_enforce_depthai_shared_commit ${ARGV1}) + set(folder "${ARGV2}") + set(output_list_var "${ARGV3}") + set(maturity "${ARGV4}") + set(commit_version_arg "${ARGV5}") + + message(STATUS "Downloading depthai device-kb") + + # END PARSE ARGUMENTS + + #DEBUG + message(STATUS "folder: ${folder}") + message(STATUS "maturity: ${maturity}") + message(STATUS "commit_version_arg: ${commit_version_arg}") + + string(TOLOWER "${maturity}" maturity_lower) + + # Switch between maturity + if("${maturity_lower}" STREQUAL "snapshot") + set(_selected_repo "${DOWNLOADER_REPO_SNAPSHOT}") + set(commit ${commit_version_arg}) + + # Create download directory string + string(CONFIGURE "@DOWNLOADER_BASE_URL@/@DOWNLOADER_REPO_SNAPSHOT@/@DOWNLOADER_ARTIFACT_PREFIX@/@commit@" _download_directory_url) + + # Create _version_commit_identifier + set(_version_commit_identifier "${commit}") + + elseif(${maturity_lower} STREQUAL "release") + set(_selected_repo "${DOWNLOADER_REPO_RELEASE}") + set(version ${commit_version_arg}) + + # Create download directory string + string(CONFIGURE "@DOWNLOADER_BASE_URL@/@DOWNLOADER_REPO_RELEASE@/@DOWNLOADER_ARTIFACT_PREFIX@/@version@" _download_directory_url) + + # Create _version_commit_identifier + set(_version_commit_identifier "${version}") + else() + # Not a recognized maturity level + message(FATAL_ERROR "Cannot download depthai-device-kb binaries. Maturity level not recognized (${maturity_lower})") + return() + endif() + + # Prints error message + macro(PrintErrorMessage status) + if(${status} EQUAL 22) + message(STATUS "Resource not found, check if commit hash is correctly specified.\n") + elseif(${status} EQUAL 28) + message(STATUS "Timeout.\n") + elseif(${status} EQUAL 99) + message(STATUS "Couldn't retrieve files correctly, checksum mismatch.") + else() + message(STATUS "Unknown error.\n") + endif() + endmacro() + + # Download files + function(DownloadAndChecksum url url_checksum output status_var) + + # Check if file already downloaded (in resources) + if(EXISTS "${output}") + get_filename_component(_filename "${output}" NAME) + message(STATUS "File already downloaded (resources): ${_filename}") + set("${status_var}" "0" PARENT_SCOPE) + return() + endif() + + # Retry again if failed + set(_num_retries_left ${DOWNLOADER_RETRY_NUM}) + # Set error by default + set("${status_var}" "1" PARENT_SCOPE) + + while(NOT ${_num_retries_left} EQUAL 0) + math(EXPR _num_retries_left "${_num_retries_left} - 1") + + # Download checksum first + file(DOWNLOAD "${url_checksum}" "${output}.checksum" STATUS _status TIMEOUT ${DOWNLOADER_TIMEOUT_S}) + # Read checksum to file + file(READ "${output}.checksum" _file_checksum) + string(REGEX REPLACE "\n$" "" _file_checksum "${_file_checksum}") + # Remove checksum file + file(REMOVE "${output}.checksum") + #CHECKS + list(GET _status 0 _status_num) + if(${_status_num}) + message(STATUS "Status error: ${_status}") + set("${status_var}" "${_status_num}" PARENT_SCOPE) + continue() + endif() + + + # Download file and validate checksum + file(DOWNLOAD "${url}" "${output}" INACTIVITY_TIMEOUT ${DOWNLOADER_INACTIVE_TIMEOUT_S} STATUS _status TIMEOUT ${DOWNLOADER_TIMEOUT_S} SHOW_PROGRESS) + + #CHECKS + list(GET _status 0 _status_num) + if(${_status_num}) + message(STATUS "Status error: ${_status}") + set("${status_var}" "${_status_num}" PARENT_SCOPE) + continue() + endif() + + # Now check if hash matches (if both files were downloaded without timeouts) + file(SHA256 ${output} _downloaded_checksum) + + # if hashes don't match + if(NOT (_downloaded_checksum STREQUAL _file_checksum)) + message(STATUS "Downloaded file checksum mismatch: ${_downloaded_checksum} != {_file_checksum}") + set("${status_var}" "99" PARENT_SCOPE) + continue() + endif() + + # If no errors happened, set status to 0 + set("${status_var}" "0" PARENT_SCOPE) + # And break the loop + break() + + endwhile() + + endfunction() + + + # Check if depthai-device-kb-shared matches + if(_depthai_shared_commit) + message(STATUS "device-kb shared commit: ${_depthai_shared_commit}") + DownloadAndChecksum( + "${_download_directory_url}/depthai-shared-commit-hash-${_version_commit_identifier}.txt" # File + "${_download_directory_url}/depthai-shared-commit-hash-${_version_commit_identifier}.txt.sha256" # File checksum + "${folder}/depthai-shared-commit-hash-${_version_commit_identifier}.txt" + status + ) + if(${status}) + + message(STATUS "Couldn't check if depthai-device-kb-shared codebase matches between device and host") + if(${_enforce_depthai_shared_commit}) + message(FATAL_ERROR "Aborting.\n") + endif() + + else() + + set(_message_mode WARNING) + if(${_enforce_depthai_shared_commit}) + set(_message_mode FATAL_ERROR) + endif() + + # Read commit hash file + file(READ "${folder}/depthai-shared-commit-hash-${_version_commit_identifier}.txt" _device_depthai_shared_commit_hash) + string(REGEX REPLACE "\n$" "" _device_depthai_shared_commit_hash "${_device_depthai_shared_commit_hash}") + string(REGEX REPLACE "\n$" "" _depthai_shared_commit "${_depthai_shared_commit}") + string(COMPARE EQUAL "${_device_depthai_shared_commit_hash}" "${_depthai_shared_commit}" _is_same) + + # If commits dont match + if(NOT ${_is_same}) + message(${_message_mode} "depthai-device-kb-shared codebases differ between device and host. Enforce (CI): ${_enforce_depthai_shared_commit} (device: ${_device_depthai_shared_commit_hash}, host: ${_depthai_shared_commit}") + else() + message(STATUS "depthai-device-kb-shared between device and host MATCH!. (device: ${_device_depthai_shared_commit_hash}, host: ${_depthai_shared_commit}") + endif() + + endif() + + endif() + + + # Download depthai-device-kb firmware package + message(STATUS "Downloading and checking depthai-device-kb-fwp.tar.xz") + DownloadAndChecksum( + "${_download_directory_url}/depthai-device-kb-fwp-${_version_commit_identifier}.tar.xz" # File + "${_download_directory_url}/depthai-device-kb-fwp-${_version_commit_identifier}.tar.xz.sha256" # File checksum + "${folder}/depthai-device-kb-fwp-${_version_commit_identifier}.tar.xz" + status + ) + if(${status}) + message(STATUS "\nCouldn't download depthai-device-kb-fwp.tar.xz\n") + PrintErrorMessage(${status}) + message(FATAL_ERROR "Aborting.\n") + endif() + # add depthai-device-kb-fwp.tar.xz to list + list(APPEND "${output_list_var}" "${folder}/depthai-device-kb-fwp-${_version_commit_identifier}.tar.xz") + + + # Set list of files as output + set("${output_list_var}" "${${output_list_var}}" PARENT_SCOPE) + +endfunction() diff --git a/bindings/python/cmake/DepthaiDownloader.cmake b/bindings/python/cmake/DepthaiDownloader.cmake new file mode 100644 index 000000000..92c73f527 --- /dev/null +++ b/bindings/python/cmake/DepthaiDownloader.cmake @@ -0,0 +1,323 @@ +# This script downloads depthai device side artifacts + +function(DepthaiDownload) + + ### VARIABLES + # Artifactory + set(DEPTHAI_BASE_URL "https://artifacts.luxonis.com/artifactory") + + # Repositories + set(DEPTHAI_REPO_SNAPSHOT "luxonis-myriad-snapshot-local") + set(DEPTHAI_REPO_RELEASE "luxonis-myriad-release-local") + + # Prefix + set(DEPTHAI_ARTIFACT_PREFIX "depthai-device-side") + + # Errors and retry count + set(DEPTHAI_TIMEOUT_S 300) + set(DEPTHAI_INACTIVE_TIMEOUT_S 60) + set(DEPTHAI_DOWNLOAD_RETRY_NUM 5) + ### END VARIABLES + + + # PARSE ARGUMENTS + set(_download_patch_only OFF) + + #if first argument PATCH_ONLY, second must be either ON/OFF + if("${ARGV2}" STREQUAL "PATCH_ONLY") + set(_depthai_shared_commit ${ARGV0}) + set(_enforce_depthai_shared_commit ${ARGV1}) + + if( ${ARGV3} ) + set(_download_patch_only ON) + else() + set(_download_patch_only OFF) + endif() + + set(folder "${ARGV4}") + set(output_list_var "${ARGV5}") + set(maturity "${ARGV6}") + set(commit "${ARGV7}") + set(version "${ARGV8}") #optional + + else() + + set(folder "${ARGV0}") + set(output_list_var "${ARGV1}") + set(maturity "${ARGV2}") + set(commit "${ARGV3}") + set(version "${ARGV4}") #optional + + endif("${ARGV2}" STREQUAL "PATCH_ONLY") + + if(_download_patch_only) + message(STATUS "Downloading depthai and patch") + else() + message(STATUS "Downloading depthai, depthai-usb2 and patch") + endif() + + # END PARSE ARGUMENTS + + #DEBUG + #message(STATUS "folder ${folder}") + #message(STATUS "maturity ${maturity}") + #message(STATUS "commit ${commit}") + #message(STATUS "version ${version}") #optional + + string(TOLOWER "${maturity}" maturity_lower) + + # Switch between maturity + if(${maturity_lower} STREQUAL "snapshot") + set(_selected_repo "${DEPTHAI_REPO_SNAPSHOT}") + + # Create download directory string + string(CONFIGURE "@DEPTHAI_BASE_URL@/@DEPTHAI_REPO_SNAPSHOT@/@DEPTHAI_ARTIFACT_PREFIX@/@commit@" _download_directory_url) + + # Create _version_commit_identifier + set(_version_commit_identifier "${commit}") + + elseif(${maturity_lower} STREQUAL "release") + set(_selected_repo "${DEPTHAI_REPO_RELEASE}") + + # TODO + # Create download directory string + #string(CONFIGURE "@DEPTHAI_BASE_URL@/@DEPTHAI_REPO_SNAPSHOT@/@DEPTHAI_ARTIFACT_PREFIX@/@_commit_hash@" _download_directory_url) + + else() + # Not a recognized maturity level + message(FATAL_ERROR "Cannot download DepthAI Device Side binaries. Maturity level not recognized (${maturity_lower})") + return() + endif() + + # Prints error message + macro(PrintErrorMessage status) + if(${status} EQUAL 22) + message(STATUS "Resource not found, check if commit hash is correctly specified.\n") + elseif(${status} EQUAL 28) + message(STATUS "Timeout.\n") + elseif(${status} EQUAL 99) + message(STATUS "Couldn't retrieve files correctly, checksum mismatch.") + else() + message(STATUS "Unknown error.\n") + endif() + endmacro() + + # Download files + function(DownloadAndChecksum url url_checksum output status_var) + + # Check if file already downloaded (in resources) + if(EXISTS "${output}") + get_filename_component(_filename "${output}" NAME) + message(STATUS "File already downloaded (resources): ${_filename}") + set("${status_var}" "0" PARENT_SCOPE) + return() + endif() + + # Retry again if failed + set(_num_retries_left ${DEPTHAI_DOWNLOAD_RETRY_NUM}) + # Set error by default + set("${status_var}" "1" PARENT_SCOPE) + + while(NOT ${_num_retries_left} EQUAL 0) + math(EXPR _num_retries_left "${_num_retries_left} - 1") + + # Download checksum first + file(DOWNLOAD "${url_checksum}" "${output}.checksum" STATUS _status TIMEOUT ${DEPTHAI_TIMEOUT_S}) + # Read checksum to file + file(READ "${output}.checksum" _file_checksum) + string(REGEX REPLACE "\n$" "" _file_checksum "${_file_checksum}") + # Remove checksum file + file(REMOVE "${output}.checksum") + #CHECKS + list(GET _status 0 _status_num) + if(${_status_num}) + message(STATUS "Status error: ${_status}") + set("${status_var}" "${_status_num}" PARENT_SCOPE) + continue() + endif() + + + # Download file and validate checksum + file(DOWNLOAD "${url}" "${output}" INACTIVITY_TIMEOUT ${DEPTHAI_INACTIVE_TIMEOUT_S} STATUS _status TIMEOUT ${DEPTHAI_TIMEOUT_S} SHOW_PROGRESS) + + #CHECKS + list(GET _status 0 _status_num) + if(${_status_num}) + message(STATUS "Status error: ${_status}") + set("${status_var}" "${_status_num}" PARENT_SCOPE) + continue() + endif() + + # Now check if hash matches (if both files were downloaded without timeouts) + file(SHA256 ${output} _downloaded_checksum) + + # if hashes don't match + if(NOT (_downloaded_checksum STREQUAL _file_checksum)) + message(STATUS "Downloaded file checksum mismatch: ${_downloaded_checksum} != {_file_checksum}") + set("${status_var}" "99" PARENT_SCOPE) + continue() + endif() + + # If no errors happened, set status to 0 + set("${status_var}" "0" PARENT_SCOPE) + # And break the loop + break() + + endwhile() + + endfunction() + + + # Check if depthai-shared matches + message(STATUS "commit: ${_depthai_shared_commit}") + if(_depthai_shared_commit) + DownloadAndChecksum( + "${_download_directory_url}/depthai-shared-commit-hash-${_version_commit_identifier}.txt" # File + "${_download_directory_url}/depthai-shared-commit-hash-${_version_commit_identifier}.sha256.checksum" # File checksum + "${folder}/depthai-shared-commit-hash-${_version_commit_identifier}.txt" + status + ) + if(${status}) + message(STATUS "Couldn't check if depthai-shared codebase matches between device and host") + if(${_enforce_depthai_shared_commit}) + message(FATAL_ERROR "Aborting.\n") + endif() + + else() + + set(_message_mode WARNING) + if(${_enforce_depthai_shared_commit}) + set(_message_mode FATAL_ERROR) + endif() + + # Read commit hash file + file(READ "${folder}/depthai-shared-commit-hash-${_version_commit_identifier}.txt" _device_depthai_shared_commit_hash) + string(REGEX REPLACE "\n$" "" _device_depthai_shared_commit_hash "${_device_depthai_shared_commit_hash}") + string(REGEX REPLACE "\n$" "" _depthai_shared_commit "${_depthai_shared_commit}") + string(COMPARE EQUAL "${_device_depthai_shared_commit_hash}" "${_depthai_shared_commit}" _is_same) + + # If commits dont match + if(NOT ${_is_same}) + message(${_message_mode} "depthai-shared codebases differ between device and host. Enforce (CI): ${_enforce_depthai_shared_commit} (device: ${_device_depthai_shared_commit_hash}, host: ${_depthai_shared_commit}") + else() + message(STATUS "depthai-shared between device and host MATCH!. (device: ${_device_depthai_shared_commit_hash}, host: ${_depthai_shared_commit}") + endif() + + endif() + + + endif() + + + # Download depthai-device firmware package + message(STATUS "Downloading and checking depthai-device-fwp.tar.xz") + DownloadAndChecksum( + "${_download_directory_url}/depthai-device-fwp-${_version_commit_identifier}.tar.xz" # File + "${_download_directory_url}/depthai-device-fwp-${_version_commit_identifier}.tar.xz.sha256" # File checksum + "${folder}/depthai-device-fwp-${_version_commit_identifier}.tar.xz" + status + ) + if(${status}) + message(STATUS "\nCouldn't download depthai-device-fwp.tar.xz\n") + PrintErrorMessage(${status}) + message(FATAL_ERROR "Aborting.\n") + endif() + # add depthai-device-fwp.tar.xz to list + list(APPEND "${output_list_var}" "${folder}/depthai-device-fwp-${_version_commit_identifier}.tar.xz") + + + + ## # depthai.cmd + ## message(STATUS "Downloading and checking depthai.cmd") + ## DownloadAndChecksum( + ## "${_download_directory_url}/depthai-${_version_commit_identifier}.cmd" # File + ## "${_download_directory_url}/depthai-${_version_commit_identifier}.sha256.checksum" # File checksum + ## "${folder}/depthai-${_version_commit_identifier}.cmd" + ## status + ## ) + ## if(${status}) + ## message(STATUS "\nCouldn't download depthai.cmd\n") + ## PrintErrorMessage(${status}) + ## message(FATAL_ERROR "Aborting.\n") + ## endif() + ## # add depthai.cmd to list + ## list(APPEND "${output_list_var}" "${folder}/depthai-${_version_commit_identifier}.cmd") + ## + + ## if(NOT _download_patch_only) + ## # depthai-usb2.cmd + ## message(STATUS "Downloading and checking depthai-usb2.cmd") + ## DownloadAndChecksum( + ## "${_download_directory_url}/depthai-usb2-${_version_commit_identifier}.cmd" # File + ## "${_download_directory_url}/depthai-usb2-${_version_commit_identifier}.sha256.checksum" # File checksum + ## "${folder}/depthai-usb2-${_version_commit_identifier}.cmd" + ## status + ## ) + + ## if(${status}) + ## message(STATUS "\nCouldn't download depthai-usb2.cmd.\n") + ## PrintErrorMessage(${status}) + ## message(FATAL_ERROR "Aborting.\n") + ## endif() + + ## # add depthai-usb2.cmd to list + ## list(APPEND "${output_list_var}" "${folder}/depthai-usb2-${_version_commit_identifier}.cmd") + + ## endif(NOT _download_patch_only) + + ## # depthai-usb2-patch.patch + ## message(STATUS "Downloading and checking depthai-usb2-patch.patch") + ## DownloadAndChecksum( + ## "${_download_directory_url}/depthai-usb2-patch-${_version_commit_identifier}.patch" # File + ## "${_download_directory_url}/depthai-usb2-patch-${_version_commit_identifier}.sha256.checksum" # File checksum + ## "${folder}/depthai-usb2-patch-${_version_commit_identifier}.patch" + ## status + ## ) + ## if(${status}) + ## message(STATUS "\nCouldn't download depthai-usb2-patch.patch.\n") + ## PrintErrorMessage(${status}) + ## message(FATAL_ERROR "Aborting.\n") + ## endif() + + ## # add depthai-usb2.cmd to list + ## list(APPEND "${output_list_var}" "${folder}/depthai-usb2-patch-${_version_commit_identifier}.patch") + + + # Propagate the variable to parent + set("${output_list_var}" "${${output_list_var}}" PARENT_SCOPE) + +endfunction() + +function(DepthaiLocal patch_only patch_only_on_off output_dir output_list_var path1 path2 path3) + + #debug + message(STATUS "patch only: ${patch_only}\non/off${patch_only_on_off}\noutput dir: ${output_dir}\nout_var: ${output_list_var}\npath1: ${path1}\npath2: ${path2}\npath3: ${path3}") + + # If patch only + if(patch_only_on_off) + if(NOT path1 OR NOT path3) + message(FATAL_ERROR "Both depthai binary and depthai usb2 patch files must be specified") + else() + configure_file("${path1}" "${output_dir}/depthai.cmd" COPYONLY) + configure_file("${path3}" "${output_dir}/depthai-usb2-patch.patch" COPYONLY) + + # Set output list + list(APPEND _resource_list "${output_dir}/depthai.cmd" "${output_dir}/depthai-usb2-patch.patch") + + endif() + else() + if(NOT path1 OR NOT path2) + message(FATAL_ERROR "Both depthai and depthai usb2 binary files must be specified") + else() + configure_file("${path1}" "${output_dir}/depthai.cmd" COPYONLY) + configure_file("${path2}" "${output_dir}/depthai-usb2.cmd" COPYONLY) + + # Set output list + list(APPEND _resource_list "${output_dir}/depthai.cmd" "${output_dir}/depthai-usb2.cmd") + + endif() + endif() + + set("${output_list_var}" "${_resource_list}" PARENT_SCOPE) + +endfunction() \ No newline at end of file diff --git a/bindings/python/cmake/Flags.cmake b/bindings/python/cmake/Flags.cmake new file mode 100644 index 000000000..39c067d52 --- /dev/null +++ b/bindings/python/cmake/Flags.cmake @@ -0,0 +1,129 @@ +## setup compilation flags +include(CMakeParseArguments) +include(CheckCXXCompilerFlag) + +# conditionally applies flag. If flag is supported by current compiler, it will be added to compile options. +function(add_flag target flag) + check_cxx_compiler_flag(${flag} FLAG_${flag}) + if (FLAG_${flag} EQUAL 1) + target_compile_options(${target} PRIVATE $<$:${flag}>) + endif () +endfunction() + +function(add_default_flags target) + cmake_parse_arguments(ADF "LEAN" "" "" ${ARGN}) + if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "^(AppleClang|Clang|GNU)$") + if(NOT ADF_LEAN) + # enable those flags + add_flag(${target} -Wall) + add_flag(${target} -Wextra) + add_flag(${target} -Woverloaded-virtual) # warn if you overload (not override) a virtual function + add_flag(${target} -Wformat=2) # warn on security issues around functions that format output (ie printf) + add_flag(${target} -Wmisleading-indentation) # (only in GCC >= 6.0) warn if indentation implies blocks where blocks do not exist + add_flag(${target} -Wduplicated-cond) # (only in GCC >= 6.0) warn if if / else chain has duplicated conditions + add_flag(${target} -Wduplicated-branches) # (only in GCC >= 7.0) warn if if / else branches have duplicated code + add_flag(${target} -Wnull-dereference) # (only in GCC >= 6.0) warn if a null dereference is detected + add_flag(${target} -Wdouble-promotion) # (GCC >= 4.6, Clang >= 3.8) warn if float is implicit promoted to double + add_flag(${target} -Wsign-compare) + add_flag(${target} -Wtype-limits) # size_t - size_t >= 0 -> always true + + # disable those flags + # add_flag(${target} -Wno-unused-command-line-argument) # clang: warning: argument unused during compilation: '--coverage' [-Wunused-command-line-argument] + # add_flag(${target} -Wno-unused-parameter) # prints too many useless warnings + # add_flag(${target} -Wno-format-nonliteral) # prints way too many warnings from spdlog + # add_flag(${target} -Wno-gnu-zero-variadic-macro-arguments) # https://stackoverflow.com/questions/21266380/is-the-gnu-zero-variadic-macro-arguments-safe-to-ignore + + # promote to errors + add_flag(${target} -Werror=self-assign-field) # error if self assign - bugprone + add_flag(${target} -Werror=unused-lambda-capture) # error if lambda capture is unused + add_flag(${target} -Werror=return-type) # warning: control reaches end of non-void function [-Wreturn-type] + add_flag(${target} -Werror=non-virtual-dtor) # warn the user if a class with virtual functions has a non-virtual destructor. This helps catch hard to track down memory errors + add_flag(${target} -Werror=sign-compare) # warn the user if they compare a signed and unsigned numbers + add_flag(${target} -Werror=reorder) # field '$1' will be initialized after field '$2' + add_flag(${target} -Werror=switch-enum) # if switch case is missing - error + endif() + + elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + # using Visual Studio C++ + add_flag(${target} -DNOMINMAX) + add_flag(${target} -DWIN32_LEAN_AND_MEAN) + + if(NOT ADF_LEAN) + # TODO(warchant): add flags https://github.com/lefticus/cppbestpractices/blob/master/02-Use_the_Tools_Available.md#msvc + endif() + + # disable INTERPROCEDURAL_OPTIMIZATION and enable /LTCG for issue https://github.com/luxonis/depthai-core/issues/334 + if(WIN32) + get_target_property(_EXPORT ${target} WINDOWS_EXPORT_ALL_SYMBOLS) + if(_EXPORT) + if(CMAKE_BUILD_TYPE) + string(TOUPPER "_${CMAKE_BUILD_TYPE}" _BUILD_TYPE) + else() + set(_BUILD_TYPE "") + endif() + set(_PROP_NAME INTERPROCEDURAL_OPTIMIZATION${_BUILD_TYPE}) + get_property(_PROP_SET TARGET ${target} PROPERTY ${_PROP_NAME} SET) + if(NOT _PROP_SET) + set(_PROP_NAME INTERPROCEDURAL_OPTIMIZATION) + endif() + get_target_property(_INTER_OPT ${target} ${_PROP_NAME}) + if(_INTER_OPT) + set_target_properties(${target} PROPERTIES ${_PROP_NAME} OFF) + # check_linker_flag() only available in cmake 3.18+ + target_link_options(${target} PRIVATE /LTCG) + endif() + unset(_BUILD_TYPE) + unset(_INTER_OPT) + unset(_PROP_NAME) + unset(_PROP_SET) + endif() + unset(_EXPORT) + endif() + endif() + +endfunction() + +# discover compiler C++ standard support +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + check_cxx_compiler_flag("-std:c++14" COMPILER_SUPPORTS_CXX14) + check_cxx_compiler_flag("-std:c++17" COMPILER_SUPPORTS_CXX17) + check_cxx_compiler_flag("-std:c++20" COMPILER_SUPPORTS_CXX20) + check_cxx_compiler_flag("-std:c++23" COMPILER_SUPPORTS_CXX23) + if(COMPILER_SUPPORTS_CXX14) + set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std:c++14") + set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std:c++14") + endif() + if(COMPILER_SUPPORTS_CXX17) + set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std:c++17") + set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std:c++17") + endif() + if(COMPILER_SUPPORTS_CXX20) + set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std:c++20") + set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std:c++20") + endif() + if(COMPILER_SUPPORTS_CXX23) + set(CMAKE_CXX23_STANDARD_COMPILE_OPTION "-std:c++23") + set(CMAKE_CXX23_EXTENSION_COMPILE_OPTION "-std:c++23") + endif() +elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "^(AppleClang|Clang|GNU)$") + check_cxx_compiler_flag("-std=c++14" COMPILER_SUPPORTS_CXX14) + check_cxx_compiler_flag("-std=c++17" COMPILER_SUPPORTS_CXX17) + check_cxx_compiler_flag("-std=c++20" COMPILER_SUPPORTS_CXX20) + check_cxx_compiler_flag("-std=c++23" COMPILER_SUPPORTS_CXX23) + if(COMPILER_SUPPORTS_CXX14) + set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std=c++14") + set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=gnu++14") + endif() + if(COMPILER_SUPPORTS_CXX17) + set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std=c++17") + set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std=gnu++17") + endif() + if(COMPILER_SUPPORTS_CXX20) + set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std=c++20") + set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std=gnu++20") + endif() + if(COMPILER_SUPPORTS_CXX23) + set(CMAKE_CXX23_STANDARD_COMPILE_OPTION "-std=c++23") + set(CMAKE_CXX23_EXTENSION_COMPILE_OPTION "-std=gnu++23") + endif() +endif() diff --git a/bindings/python/cmake/GitCommitHash.cmake b/bindings/python/cmake/GitCommitHash.cmake new file mode 100644 index 000000000..0b1a406ae --- /dev/null +++ b/bindings/python/cmake/GitCommitHash.cmake @@ -0,0 +1,19 @@ +# for commit hash +find_package(Git) + +set(commit_version "unknown") + +if(GIT_FOUND) + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse HEAD + WORKING_DIRECTORY "${local_dir}" + OUTPUT_VARIABLE commit_version + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) +else() + message(STATUS "GIT module not found") +endif() + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../../shared/version.hpp.in ${CMAKE_CURRENT_SOURCE_DIR}/../../shared/version.hpp @ONLY) + diff --git a/bindings/python/cmake/default_docstring.hpp.in b/bindings/python/cmake/default_docstring.hpp.in new file mode 100644 index 000000000..d3ee0a244 --- /dev/null +++ b/bindings/python/cmake/default_docstring.hpp.in @@ -0,0 +1,3 @@ +// Default DOC define, which is nullptr aka no docstring +// This case covers when docstrings couldn't be generated +#define DOC(...) ((const char*) nullptr) diff --git a/bindings/python/cmake/depthaiConfig.cmake.in b/bindings/python/cmake/depthaiConfig.cmake.in new file mode 100644 index 000000000..dfe96ad73 --- /dev/null +++ b/bindings/python/cmake/depthaiConfig.cmake.in @@ -0,0 +1,22 @@ +# Get whether library was build as shared or not +set(DEPTHAI_SHARED_LIBS @BUILD_SHARED_LIBS@) + +# Get library options +# Get whether library was build with Backward or not +set(DEPTHAI_ENABLE_BACKWARD @DEPTHAI_ENABLE_BACKWARD@) +set(DEPTHAI_XLINK_LOCAL @DEPTHAI_XLINK_LOCAL@) + +# Specify that this is config mode (Called by find_package) +set(CONFIG_MODE TRUE) + +# Compute the installation prefix relative to this file. +set(_IMPORT_PREFIX "@DEPTHAI_DEPENDENCIES_INSTALLATION_PATH_REL@") + +# Add dependencies file +include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Dependencies.cmake") + +# Add the targets file +include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_EXPORT_GROUP@.cmake") + +# Cleanup +set(_IMPORT_PREFIX) diff --git a/bindings/python/cmake/depthaiDependencies.cmake b/bindings/python/cmake/depthaiDependencies.cmake new file mode 100644 index 000000000..214460922 --- /dev/null +++ b/bindings/python/cmake/depthaiDependencies.cmake @@ -0,0 +1,105 @@ +if(CONFIG_MODE) + set(_DEPTHAI_PREFIX_PATH_ORIGINAL ${CMAKE_PREFIX_PATH}) + set(_DEPTHAI_FIND_ROOT_PATH_MODE_PACKAGE_ORIGINAL ${CMAKE_FIND_ROOT_PATH_MODE_PACKAGE}) + # Fixes Android NDK build, where prefix path is ignored as its not inside sysroot + set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE "BOTH") + # Sets where to search for packages about to follow + set(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_LIST_DIR}/${_IMPORT_PREFIX}" ${CMAKE_PREFIX_PATH}) + set(_QUIET "QUIET") +else() + set(DEPTHAI_SHARED_LIBS ${BUILD_SHARED_LIBS}) + hunter_add_package(nlohmann_json) + if(NOT DEPTHAI_XLINK_LOCAL) + hunter_add_package(XLink) + endif() + hunter_add_package(BZip2) + hunter_add_package(FP16) + hunter_add_package(libarchive-luxonis) + hunter_add_package(spdlog) + hunter_add_package(ZLIB) + hunter_add_package(httplib) + if(DEPTHAI_ENABLE_BACKWARD) + hunter_add_package(Backward) + endif() + hunter_add_package(libnop) +endif() + +# If library was build as static, find all dependencies +if(NOT CONFIG_MODE OR (CONFIG_MODE AND NOT DEPTHAI_SHARED_LIBS)) + + # BZip2 (for bspatch) + find_package(BZip2 ${_QUIET} CONFIG REQUIRED) + + # FP16 for conversions + find_package(FP16 ${_QUIET} CONFIG REQUIRED) + + # libarchive for firmware packages + find_package(archive_static ${_QUIET} CONFIG REQUIRED) + find_package(lzma ${_QUIET} CONFIG REQUIRED) + # ZLIB for compressing Apps + find_package(ZLIB CONFIG REQUIRED) + + # spdlog for library and device logging + find_package(spdlog ${_QUIET} CONFIG REQUIRED) + + # httplib for Gate communication + find_package(httplib ${_QUIET} CONFIG REQUIRED) + + # Backward + if(DEPTHAI_ENABLE_BACKWARD) + # Disable automatic check for additional stack unwinding libraries + # Just use the default compiler one + set(STACK_DETAILS_AUTO_DETECT FALSE CACHE BOOL "Auto detect backward's stack details dependencies") + find_package(Backward ${_QUIET} CONFIG REQUIRED) + unset(STACK_DETAILS_AUTO_DETECT) + endif() +endif() + +# Xtensor +if(DEPTHAI_XTENSOR_SUPPORT) + get_filename_component(PARENT_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/.. ABSOLUTE) + add_subdirectory("${PARENT_DIRECTORY}/3rdparty/xtl" xtl) + add_subdirectory("${PARENT_DIRECTORY}/3rdparty/xtensor" xtensor) +endif() + +# Add threads (c++) +find_package(Threads ${_QUIET} REQUIRED) + +# Nlohmann JSON +find_package(nlohmann_json 3.6.0 ${_QUIET} CONFIG REQUIRED) + +# libnop for serialization +find_package(libnop ${_QUIET} CONFIG REQUIRED) + +# XLink +if(DEPTHAI_XLINK_LOCAL AND (NOT CONFIG_MODE)) + set(_BUILD_SHARED_LIBS_SAVED "${BUILD_SHARED_LIBS}") + set(BUILD_SHARED_LIBS OFF) + add_subdirectory("${DEPTHAI_XLINK_LOCAL}" ${CMAKE_CURRENT_BINARY_DIR}/XLink) + set(BUILD_SHARED_LIBS "${_BUILD_SHARED_LIBS_SAVED}") + unset(_BUILD_SHARED_LIBS_SAVED) + list(APPEND targets_to_export XLink XLinkPublic) +else() + # TODO(themarpe) - might be required + # elseif(NOT DEPTHAI_XLINK_LOCAL) + find_package(XLink ${_QUIET} CONFIG REQUIRED HINTS "${CMAKE_CURRENT_LIST_DIR}/XLink" "${CMAKE_CURRENT_LIST_DIR}/../XLink") +endif() + +# OpenCV 4 - (optional, quiet always) +find_package(OpenCV 4 QUIET CONFIG) + +# include optional dependency cmake +if(DEPTHAI_DEPENDENCY_INCLUDE) + include(${DEPTHAI_DEPENDENCY_INCLUDE} OPTIONAL) +endif() + +# Cleanup +if(CONFIG_MODE) + set(CMAKE_PREFIX_PATH ${_DEPTHAI_PREFIX_PATH_ORIGINAL}) + set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ${_DEPTHAI_FIND_ROOT_PATH_MODE_PACKAGE_ORIGINAL}) + unset(_DEPTHAI_PREFIX_PATH_ORIGINAL) + unset(_DEPTHAI_FIND_ROOT_PATH_MODE_PACKAGE_ORIGINAL) + unset(_QUIET) +else() + set(DEPTHAI_SHARED_LIBS) +endif() diff --git a/bindings/python/cmake/docstring.hpp.in b/bindings/python/cmake/docstring.hpp.in new file mode 100644 index 000000000..6706b0961 --- /dev/null +++ b/bindings/python/cmake/docstring.hpp.in @@ -0,0 +1 @@ +#include "@docstring_input_path@" diff --git a/bindings/python/cmake/pybind11-mkdoc.cmake b/bindings/python/cmake/pybind11-mkdoc.cmake new file mode 100644 index 000000000..e399bb60d --- /dev/null +++ b/bindings/python/cmake/pybind11-mkdoc.cmake @@ -0,0 +1,85 @@ +# Helper to create a pybind11_mkdoc target which takes +include(target-public-headers) + +# Usage: +# target_pybind11_mkdoc_setup([path/to/output/docstring.hpp] [Library for which to generate: target-name] [Enforce pybind11_mkdoc existing ON/OFF]) +function(target_pybind11_mkdoc_setup output_file target enforce) + + # Get unaliased target if alias target passed in + get_target_property(original_target ${target} ALIASED_TARGET) + if(original_target) + set(target ${original_target}) + endif() + + # gets target public headers + get_target_public_headers(${target} header_files) + + # Setup mkdoc target + pybind11_mkdoc_setup_internal("${target}" "${output_file}" "${header_files}" ${enforce}) + +endfunction() + +# Internal helper, sets up pybind11_mkdoc target +function(pybind11_mkdoc_setup_internal target output_path mkdoc_headers enforce) + + # constants + set(PYBIND11_MKDOC_MODULE_NAME "pybind11_mkdoc") + set(PYBIND11_MKDOC_TARGET_NAME "pybind11_mkdoc") + + # Execute module pybind11_mkdoc to check if present + message(STATUS "Checking for pybind11_mkdoc") + execute_process(COMMAND ${PYTHON_EXECUTABLE} -m ${PYBIND11_MKDOC_MODULE_NAME} --help RESULT_VARIABLE error OUTPUT_QUIET ERROR_QUIET) + if(error) + set(message "Checking for pybind11_mkdoc - not found, docstrings not available") + if(NOT enforce) + message(STATUS ${message}) + else() + message(FATAL_ERROR ${message}) + endif() + # Exit + return() + else() + message(STATUS "Checking for pybind11_mkdoc - found, docstrings available") + endif() + + # Prepare the output folder for the mkdoc + get_filename_component(output_directory "${output_path}" DIRECTORY) + # Create the command + add_custom_command( + OUTPUT "${output_path}" + # Create directory first (if it doesn't exist) + COMMAND ${CMAKE_COMMAND} -E make_directory "${output_directory}" + # Execute mkdoc + COMMAND + ${PYTHON_EXECUTABLE} + -m ${PYBIND11_MKDOC_MODULE_NAME} + # Docstring wrap width + -w 80 + -o "${output_path}" + # C++ standard + -std=c++17 + # List of include directories + "-I$,;-I>" + # List of compiler definitions + "-D$,;-D>" + # List of headers for which to generate docstrings + "${mkdoc_headers}" + # Redirect stderr to not spam output + # 2> /dev/null + DEPENDS ${mkdoc_headers} #${target} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + COMMENT "Creating docstrings with ${PYTHON_EXECUTABLE} -m ${PYBIND11_MKDOC_MODULE_NAME} ..." + VERBATIM + COMMAND_EXPAND_LISTS + ) + + # Create a target + add_custom_target( + ${PYBIND11_MKDOC_TARGET_NAME} + DEPENDS "${output_path}" + ) + + # Force target build + file(TOUCH_NOCREATE ${mkdoc_headers}) + +endfunction() diff --git a/bindings/python/cmake/sanitizers/FindASan.cmake b/bindings/python/cmake/sanitizers/FindASan.cmake new file mode 100644 index 000000000..98ea7cb31 --- /dev/null +++ b/bindings/python/cmake/sanitizers/FindASan.cmake @@ -0,0 +1,59 @@ +# The MIT License (MIT) +# +# Copyright (c) +# 2013 Matthew Arsenault +# 2015-2016 RWTH Aachen University, Federal Republic of Germany +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +option(SANITIZE_ADDRESS "Enable AddressSanitizer for sanitized targets." Off) + +set(FLAG_CANDIDATES + # Clang 3.2+ use this version. The no-omit-frame-pointer option is optional. + "-g -fsanitize=address -fno-omit-frame-pointer" + "-g -fsanitize=address" + + # Older deprecated flag for ASan + "-g -faddress-sanitizer" +) + + +if (SANITIZE_ADDRESS AND (SANITIZE_THREAD OR SANITIZE_MEMORY)) + message(FATAL_ERROR "AddressSanitizer is not compatible with " + "ThreadSanitizer or MemorySanitizer.") +endif () + + +include(sanitize-helpers) + +if (SANITIZE_ADDRESS) + sanitizer_check_compiler_flags("${FLAG_CANDIDATES}" "AddressSanitizer" + "ASan") + + find_program(ASan_WRAPPER "asan-wrapper" PATHS ${CMAKE_MODULE_PATH}) + mark_as_advanced(ASan_WRAPPER) +endif () + +function (add_sanitize_address TARGET) + if (NOT SANITIZE_ADDRESS) + return() + endif () + + sanitizer_add_flags(${TARGET} "AddressSanitizer" "ASan") +endfunction () diff --git a/bindings/python/cmake/sanitizers/FindMSan.cmake b/bindings/python/cmake/sanitizers/FindMSan.cmake new file mode 100644 index 000000000..22d0050e9 --- /dev/null +++ b/bindings/python/cmake/sanitizers/FindMSan.cmake @@ -0,0 +1,57 @@ +# The MIT License (MIT) +# +# Copyright (c) +# 2013 Matthew Arsenault +# 2015-2016 RWTH Aachen University, Federal Republic of Germany +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +option(SANITIZE_MEMORY "Enable MemorySanitizer for sanitized targets." Off) + +set(FLAG_CANDIDATES + "-g -fsanitize=memory" +) + + +include(sanitize-helpers) + +if (SANITIZE_MEMORY) + if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Linux") + message(WARNING "MemorySanitizer disabled for target ${TARGET} because " + "MemorySanitizer is supported for Linux systems only.") + set(SANITIZE_MEMORY Off CACHE BOOL + "Enable MemorySanitizer for sanitized targets." FORCE) + elseif (NOT ${CMAKE_SIZEOF_VOID_P} EQUAL 8) + message(WARNING "MemorySanitizer disabled for target ${TARGET} because " + "MemorySanitizer is supported for 64bit systems only.") + set(SANITIZE_MEMORY Off CACHE BOOL + "Enable MemorySanitizer for sanitized targets." FORCE) + else () + sanitizer_check_compiler_flags("${FLAG_CANDIDATES}" "MemorySanitizer" + "MSan") + endif () +endif () + +function (add_sanitize_memory TARGET) + if (NOT SANITIZE_MEMORY) + return() + endif () + + sanitizer_add_flags(${TARGET} "MemorySanitizer" "MSan") +endfunction () diff --git a/bindings/python/cmake/sanitizers/FindSanitizers.cmake b/bindings/python/cmake/sanitizers/FindSanitizers.cmake new file mode 100755 index 000000000..101bab843 --- /dev/null +++ b/bindings/python/cmake/sanitizers/FindSanitizers.cmake @@ -0,0 +1,94 @@ +# The MIT License (MIT) +# +# Copyright (c) +# 2013 Matthew Arsenault +# 2015-2016 RWTH Aachen University, Federal Republic of Germany +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# If any of the used compiler is a GNU compiler, add a second option to static +# link against the sanitizers. +option(SANITIZE_LINK_STATIC "Try to link static against sanitizers." Off) + + + + +set(FIND_QUIETLY_FLAG "") +if (DEFINED Sanitizers_FIND_QUIETLY) + set(FIND_QUIETLY_FLAG "QUIET") +endif () + +find_package(ASan ${FIND_QUIETLY_FLAG}) +find_package(TSan ${FIND_QUIETLY_FLAG}) +find_package(MSan ${FIND_QUIETLY_FLAG}) +find_package(UBSan ${FIND_QUIETLY_FLAG}) + + + + +function(sanitizer_add_blacklist_file FILE) + if(NOT IS_ABSOLUTE ${FILE}) + set(FILE "${CMAKE_CURRENT_SOURCE_DIR}/${FILE}") + endif() + get_filename_component(FILE "${FILE}" REALPATH) + + sanitizer_check_compiler_flags("-fsanitize-blacklist=${FILE}" + "SanitizerBlacklist" "SanBlist") +endfunction() + +function(add_sanitizers ...) + # If no sanitizer is enabled, return immediately. + if (NOT (SANITIZE_ADDRESS OR SANITIZE_MEMORY OR SANITIZE_THREAD OR + SANITIZE_UNDEFINED)) + return() + endif () + + foreach (TARGET ${ARGV}) + # Check if this target will be compiled by exactly one compiler. Other- + # wise sanitizers can't be used and a warning should be printed once. + get_target_property(TARGET_TYPE ${TARGET} TYPE) + if (TARGET_TYPE STREQUAL "INTERFACE_LIBRARY") + message(WARNING "Can't use any sanitizers for target ${TARGET}, " + "because it is an interface library and cannot be " + "compiled directly.") + return() + endif () + sanitizer_target_compilers(${TARGET} TARGET_COMPILER) + list(LENGTH TARGET_COMPILER NUM_COMPILERS) + if (NUM_COMPILERS GREATER 1) + message(WARNING "Can't use any sanitizers for target ${TARGET}, " + "because it will be compiled by incompatible compilers. " + "Target will be compiled without sanitizers.") + return() + + # If the target is compiled by no or no known compiler, give a warning. + elseif (NUM_COMPILERS EQUAL 0) + message(WARNING "Sanitizers for target ${TARGET} may not be" + " usable, because it uses no or an unknown compiler. " + "This is a false warning for targets using only " + "object lib(s) as input.") + endif () + + # Add sanitizers for target. + add_sanitize_address(${TARGET}) + add_sanitize_thread(${TARGET}) + add_sanitize_memory(${TARGET}) + add_sanitize_undefined(${TARGET}) + endforeach () +endfunction(add_sanitizers) diff --git a/bindings/python/cmake/sanitizers/FindTSan.cmake b/bindings/python/cmake/sanitizers/FindTSan.cmake new file mode 100644 index 000000000..3cba3c03b --- /dev/null +++ b/bindings/python/cmake/sanitizers/FindTSan.cmake @@ -0,0 +1,65 @@ +# The MIT License (MIT) +# +# Copyright (c) +# 2013 Matthew Arsenault +# 2015-2016 RWTH Aachen University, Federal Republic of Germany +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +option(SANITIZE_THREAD "Enable ThreadSanitizer for sanitized targets." Off) + +set(FLAG_CANDIDATES + "-g -fsanitize=thread" +) + + +# ThreadSanitizer is not compatible with MemorySanitizer. +if (SANITIZE_THREAD AND SANITIZE_MEMORY) + message(FATAL_ERROR "ThreadSanitizer is not compatible with " + "MemorySanitizer.") +endif () + + +include(sanitize-helpers) + +if (SANITIZE_THREAD) + if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND + NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") + message(WARNING "ThreadSanitizer disabled for target ${TARGET} because " + "ThreadSanitizer is supported for Linux systems and macOS only.") + set(SANITIZE_THREAD Off CACHE BOOL + "Enable ThreadSanitizer for sanitized targets." FORCE) + elseif (NOT ${CMAKE_SIZEOF_VOID_P} EQUAL 8) + message(WARNING "ThreadSanitizer disabled for target ${TARGET} because " + "ThreadSanitizer is supported for 64bit systems only.") + set(SANITIZE_THREAD Off CACHE BOOL + "Enable ThreadSanitizer for sanitized targets." FORCE) + else () + sanitizer_check_compiler_flags("${FLAG_CANDIDATES}" "ThreadSanitizer" + "TSan") + endif () +endif () + +function (add_sanitize_thread TARGET) + if (NOT SANITIZE_THREAD) + return() + endif () + + sanitizer_add_flags(${TARGET} "ThreadSanitizer" "TSan") +endfunction () diff --git a/bindings/python/cmake/sanitizers/FindUBSan.cmake b/bindings/python/cmake/sanitizers/FindUBSan.cmake new file mode 100644 index 000000000..ae103f717 --- /dev/null +++ b/bindings/python/cmake/sanitizers/FindUBSan.cmake @@ -0,0 +1,46 @@ +# The MIT License (MIT) +# +# Copyright (c) +# 2013 Matthew Arsenault +# 2015-2016 RWTH Aachen University, Federal Republic of Germany +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +option(SANITIZE_UNDEFINED + "Enable UndefinedBehaviorSanitizer for sanitized targets." Off) + +set(FLAG_CANDIDATES + "-g -fsanitize=undefined" +) + + +include(sanitize-helpers) + +if (SANITIZE_UNDEFINED) + sanitizer_check_compiler_flags("${FLAG_CANDIDATES}" + "UndefinedBehaviorSanitizer" "UBSan") +endif () + +function (add_sanitize_undefined TARGET) + if (NOT SANITIZE_UNDEFINED) + return() + endif () + + sanitizer_add_flags(${TARGET} "UndefinedBehaviorSanitizer" "UBSan") +endfunction () diff --git a/bindings/python/cmake/sanitizers/asan-wrapper b/bindings/python/cmake/sanitizers/asan-wrapper new file mode 100755 index 000000000..5d5410337 --- /dev/null +++ b/bindings/python/cmake/sanitizers/asan-wrapper @@ -0,0 +1,55 @@ +#!/bin/sh + +# The MIT License (MIT) +# +# Copyright (c) +# 2013 Matthew Arsenault +# 2015-2016 RWTH Aachen University, Federal Republic of Germany +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# This script is a wrapper for AddressSanitizer. In some special cases you need +# to preload AddressSanitizer to avoid error messages - e.g. if you're +# preloading another library to your application. At the moment this script will +# only do something, if we're running on a Linux platform. OSX might not be +# affected. + + +# Exit immediately, if platform is not Linux. +if [ "$(uname)" != "Linux" ] +then + exec $@ +fi + + +# Get the used libasan of the application ($1). If a libasan was found, it will +# be prepended to LD_PRELOAD. +libasan=$(ldd $1 | grep libasan | sed "s/^[[:space:]]//" | cut -d' ' -f1) +if [ -n "$libasan" ] +then + if [ -n "$LD_PRELOAD" ] + then + export LD_PRELOAD="$libasan:$LD_PRELOAD" + else + export LD_PRELOAD="$libasan" + fi +fi + +# Execute the application. +exec $@ diff --git a/bindings/python/cmake/sanitizers/sanitize-helpers.cmake b/bindings/python/cmake/sanitizers/sanitize-helpers.cmake new file mode 100755 index 000000000..3649b0742 --- /dev/null +++ b/bindings/python/cmake/sanitizers/sanitize-helpers.cmake @@ -0,0 +1,177 @@ +# The MIT License (MIT) +# +# Copyright (c) +# 2013 Matthew Arsenault +# 2015-2016 RWTH Aachen University, Federal Republic of Germany +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# Helper function to get the language of a source file. +function (sanitizer_lang_of_source FILE RETURN_VAR) + get_filename_component(LONGEST_EXT "${FILE}" EXT) + # If extension is empty return. This can happen for extensionless headers + if("${LONGEST_EXT}" STREQUAL "") + set(${RETURN_VAR} "" PARENT_SCOPE) + return() + endif() + # Get shortest extension as some files can have dot in their names + string(REGEX REPLACE "^.*(\\.[^.]+)$" "\\1" FILE_EXT ${LONGEST_EXT}) + string(TOLOWER "${FILE_EXT}" FILE_EXT) + string(SUBSTRING "${FILE_EXT}" 1 -1 FILE_EXT) + + get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) + foreach (LANG ${ENABLED_LANGUAGES}) + list(FIND CMAKE_${LANG}_SOURCE_FILE_EXTENSIONS "${FILE_EXT}" TEMP) + if (NOT ${TEMP} EQUAL -1) + set(${RETURN_VAR} "${LANG}" PARENT_SCOPE) + return() + endif () + endforeach() + + set(${RETURN_VAR} "" PARENT_SCOPE) +endfunction () + + +# Helper function to get compilers used by a target. +function (sanitizer_target_compilers TARGET RETURN_VAR) + # Check if all sources for target use the same compiler. If a target uses + # e.g. C and Fortran mixed and uses different compilers (e.g. clang and + # gfortran) this can trigger huge problems, because different compilers may + # use different implementations for sanitizers. + set(BUFFER "") + get_target_property(TSOURCES ${TARGET} SOURCES) + foreach (FILE ${TSOURCES}) + # If expression was found, FILE is a generator-expression for an object + # library. Object libraries will be ignored. + string(REGEX MATCH "TARGET_OBJECTS:([^ >]+)" _file ${FILE}) + if ("${_file}" STREQUAL "") + sanitizer_lang_of_source(${FILE} LANG) + if (LANG) + list(APPEND BUFFER ${CMAKE_${LANG}_COMPILER_ID}) + endif () + endif () + endforeach () + + list(REMOVE_DUPLICATES BUFFER) + set(${RETURN_VAR} "${BUFFER}" PARENT_SCOPE) +endfunction () + + +# Helper function to check compiler flags for language compiler. +function (sanitizer_check_compiler_flag FLAG LANG VARIABLE) + if (${LANG} STREQUAL "C") + include(CheckCCompilerFlag) + check_c_compiler_flag("${FLAG}" ${VARIABLE}) + + elseif (${LANG} STREQUAL "CXX") + include(CheckCXXCompilerFlag) + check_cxx_compiler_flag("${FLAG}" ${VARIABLE}) + + elseif (${LANG} STREQUAL "Fortran") + # CheckFortranCompilerFlag was introduced in CMake 3.x. To be compatible + # with older Cmake versions, we will check if this module is present + # before we use it. Otherwise we will define Fortran coverage support as + # not available. + include(CheckFortranCompilerFlag OPTIONAL RESULT_VARIABLE INCLUDED) + if (INCLUDED) + check_fortran_compiler_flag("${FLAG}" ${VARIABLE}) + elseif (NOT CMAKE_REQUIRED_QUIET) + message(STATUS "Performing Test ${VARIABLE}") + message(STATUS "Performing Test ${VARIABLE}" + " - Failed (Check not supported)") + endif () + endif() +endfunction () + + +# Helper function to test compiler flags. +function (sanitizer_check_compiler_flags FLAG_CANDIDATES NAME PREFIX) + set(CMAKE_REQUIRED_QUIET ${${PREFIX}_FIND_QUIETLY}) + + get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) + foreach (LANG ${ENABLED_LANGUAGES}) + # Sanitizer flags are not dependend on language, but the used compiler. + # So instead of searching flags foreach language, search flags foreach + # compiler used. + set(COMPILER ${CMAKE_${LANG}_COMPILER_ID}) + if (NOT DEFINED ${PREFIX}_${COMPILER}_FLAGS) + foreach (FLAG ${FLAG_CANDIDATES}) + if(NOT CMAKE_REQUIRED_QUIET) + message(STATUS "Try ${COMPILER} ${NAME} flag = [${FLAG}]") + endif() + + set(CMAKE_REQUIRED_FLAGS "${FLAG}") + unset(${PREFIX}_FLAG_DETECTED CACHE) + sanitizer_check_compiler_flag("${FLAG}" ${LANG} + ${PREFIX}_FLAG_DETECTED) + + if (${PREFIX}_FLAG_DETECTED) + # If compiler is a GNU compiler, search for static flag, if + # SANITIZE_LINK_STATIC is enabled. + if (SANITIZE_LINK_STATIC AND (${COMPILER} STREQUAL "GNU")) + string(TOLOWER ${PREFIX} PREFIX_lower) + sanitizer_check_compiler_flag( + "-static-lib${PREFIX_lower}" ${LANG} + ${PREFIX}_STATIC_FLAG_DETECTED) + + if (${PREFIX}_STATIC_FLAG_DETECTED) + set(FLAG "-static-lib${PREFIX_lower} ${FLAG}") + endif () + endif () + + set(${PREFIX}_${COMPILER}_FLAGS "${FLAG}" CACHE STRING + "${NAME} flags for ${COMPILER} compiler.") + mark_as_advanced(${PREFIX}_${COMPILER}_FLAGS) + break() + endif () + endforeach () + + if (NOT ${PREFIX}_FLAG_DETECTED) + set(${PREFIX}_${COMPILER}_FLAGS "" CACHE STRING + "${NAME} flags for ${COMPILER} compiler.") + mark_as_advanced(${PREFIX}_${COMPILER}_FLAGS) + + message(WARNING "${NAME} is not available for ${COMPILER} " + "compiler. Targets using this compiler will be " + "compiled without ${NAME}.") + endif () + endif () + endforeach () +endfunction () + + +# Helper to assign sanitizer flags for TARGET. +function (sanitizer_add_flags TARGET NAME PREFIX) + # Get list of compilers used by target and check, if sanitizer is available + # for this target. Other compiler checks like check for conflicting + # compilers will be done in add_sanitizers function. + sanitizer_target_compilers(${TARGET} TARGET_COMPILER) + list(LENGTH TARGET_COMPILER NUM_COMPILERS) + if ("${${PREFIX}_${TARGET_COMPILER}_FLAGS}" STREQUAL "") + return() + endif() + + # Set compile- and link-flags for target. + set_property(TARGET ${TARGET} APPEND_STRING + PROPERTY COMPILE_FLAGS " ${${PREFIX}_${TARGET_COMPILER}_FLAGS}") + set_property(TARGET ${TARGET} APPEND_STRING + PROPERTY COMPILE_FLAGS " ${SanBlist_${TARGET_COMPILER}_FLAGS}") + set_property(TARGET ${TARGET} APPEND_STRING + PROPERTY LINK_FLAGS " ${${PREFIX}_${TARGET_COMPILER}_FLAGS}") +endfunction () diff --git a/bindings/python/cmake/target-public-headers.cmake b/bindings/python/cmake/target-public-headers.cmake new file mode 100644 index 000000000..f597d188c --- /dev/null +++ b/bindings/python/cmake/target-public-headers.cmake @@ -0,0 +1,73 @@ +# CMake helper script which defines a function to retrieve targets public headers (if separated in different directories) + +function(get_target_public_headers target output_variable_name) + + # Get both interface include directories and system include directories + get_target_property(header_dirs ${target} INTERFACE_INCLUDE_DIRECTORIES) + get_target_property(header_system_dirs ${target} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES) + + # Remove system include directories + set(non_system_dirs ${header_dirs}) + foreach(sys_dir ${header_system_dirs}) + list(REMOVE_ITEM non_system_dirs "${sys_dir}") + endforeach() + + # Get all header files + header_directories("${non_system_dirs}" header_files) + + set(${output_variable_name} ${header_files} PARENT_SCOPE) + +endfunction() + + +function(get_header_files include_directories output_variable_name) + + # Get all header files + header_directories("${include_directories}" header_files) + + # Set to parent + set(${output_variable_name} ${header_files} PARENT_SCOPE) + +endfunction() + +# Internal helper, converts header directory list to list of .hpp files +macro(header_directories header_dirs return_list) + + #message(STATUS "folders: ${header_dirs}") + foreach(header_dir ${header_dirs}) + # only use build_interface includes + + string(REGEX MATCHALL "\\$" tmp_output_variable "${header_dir}") + #message(STATUS "inspecting folder: ${header_dir}, stripped ${hdir}, regex count ${CMAKE_MATCH_COUNT}, regex match 0 and 1, ${CMAKE_MATCH_0}, ${CMAKE_MATCH_1}") + # If regex matched and path is present + if(CMAKE_MATCH_COUNT GREATER 0) + set(hdir "${CMAKE_MATCH_1}") + else() + # Strip generator expresssions + string(GENEX_STRIP "${header_dir}" hdir) + endif() + + # if hdir isn't an empty path + if(hdir) + + #message(STATUS "inspecting folder: ${hdir}") + file(GLOB_RECURSE new_list "${hdir}/*.hpp") + set(file_list "") + + foreach(file_path ${new_list}) + #message(STATUS "inspecting file: ${file_path}") + set(file_list "${file_list}" ${file_path}) + endforeach() + + list(REMOVE_DUPLICATES file_list) + set(${return_list} "${${return_list}}" "${file_list}") + + endif() + + endforeach() + +endmacro() + + + + diff --git a/bindings/python/cmake/toolchain/asan-ubsan.cmake b/bindings/python/cmake/toolchain/asan-ubsan.cmake new file mode 100644 index 000000000..309ca69ce --- /dev/null +++ b/bindings/python/cmake/toolchain/asan-ubsan.cmake @@ -0,0 +1,12 @@ +set(_internal_flags_sanitizer "-fno-omit-frame-pointer -fsanitize=address,undefined -fno-sanitize=pointer-overflow") +set(CMAKE_C_FLAGS ${_internal_flags_sanitizer}) +set(CMAKE_CXX_FLAGS ${_internal_flags_sanitizer}) +set(CMAKE_C_FLAGS_INIT ${_internal_flags_sanitizer}) +set(CMAKE_CXX_FLAGS_INIT ${_internal_flags_sanitizer}) +set(CMAKE_EXE_LINKER_FLAGS ${_internal_flags_sanitizer}) +set(CMAKE_EXE_LINKER_FLAGS_INIT ${_internal_flags_sanitizer}) +set(CMAKE_SHARED_LINKER_FLAGS ${_internal_flags_sanitizer}) +set(CMAKE_SHARED_LINKER_FLAGS_INIT ${_internal_flags_sanitizer}) +set(CMAKE_MODULE_LINKER_FLAGS ${_internal_flags_sanitizer}) +set(CMAKE_MODULE_LINKER_FLAGS_INIT ${_internal_flags_sanitizer}) +set(_internal_flags_sanitizer) diff --git a/bindings/python/cmake/toolchain/asan.cmake b/bindings/python/cmake/toolchain/asan.cmake new file mode 100644 index 000000000..2388e0b0e --- /dev/null +++ b/bindings/python/cmake/toolchain/asan.cmake @@ -0,0 +1,12 @@ +set(_internal_flags_sanitizer "-fno-omit-frame-pointer -fsanitize=address") +set(CMAKE_C_FLAGS ${_internal_flags_sanitizer}) +set(CMAKE_CXX_FLAGS ${_internal_flags_sanitizer}) +set(CMAKE_C_FLAGS_INIT ${_internal_flags_sanitizer}) +set(CMAKE_CXX_FLAGS_INIT ${_internal_flags_sanitizer}) +set(CMAKE_EXE_LINKER_FLAGS ${_internal_flags_sanitizer}) +set(CMAKE_EXE_LINKER_FLAGS_INIT ${_internal_flags_sanitizer}) +set(CMAKE_SHARED_LINKER_FLAGS ${_internal_flags_sanitizer}) +set(CMAKE_SHARED_LINKER_FLAGS_INIT ${_internal_flags_sanitizer}) +set(CMAKE_MODULE_LINKER_FLAGS ${_internal_flags_sanitizer}) +set(CMAKE_MODULE_LINKER_FLAGS_INIT ${_internal_flags_sanitizer}) +set(_internal_flags_sanitizer) diff --git a/bindings/python/cmake/toolchain/custom.cmake.in b/bindings/python/cmake/toolchain/custom.cmake.in new file mode 100644 index 000000000..fa5bc5ebb --- /dev/null +++ b/bindings/python/cmake/toolchain/custom.cmake.in @@ -0,0 +1,63 @@ +# STEP 1: Lock variables + +if(NOT "@ANDROID_ABI@" STREQUAL "") + set(ANDROID_ABI "@ANDROID_ABI@") +endif() +if(NOT "@ANDROID_PLATFORM@" STREQUAL "") + set(ANDROID_PLATFORM "@ANDROID_PLATFORM@") +endif() +if(NOT "@ANDROID_STL@" STREQUAL "") + set(ANDROID_STL "@ANDROID_STL@") +endif() +if(NOT "@ANDROID_ARM_NEON@" STREQUAL "") + set(ANDROID_ARM_NEON "@ANDROID_ARM_NEON@") +endif() +if(NOT "@ANDROID_ARM_MODE@" STREQUAL "") + set(ANDROID_ARM_MODE "@ANDROID_ARM_MODE@") +endif() + +# STEP 2: Include original toolchain (if exists) + +if(NOT "@CMAKE_TOOLCHAIN_FILE@" STREQUAL "") + + # Original toolchain file will be saved in variable: + # * _INTERNAL_DEPTHAI_ORIGINAL_CMAKE_TOOLCHAIN_FILE + + if("@_INTERNAL_DEPTHAI_ORIGINAL_CMAKE_TOOLCHAIN_FILE@" STREQUAL "") + # Variable not set, initial project configuration. + # Path to original toolchain saved in CMAKE_TOOLCHAIN_FILE. + if(NOT EXISTS "@CMAKE_TOOLCHAIN_FILE@") + message( + FATAL_ERROR "File not found: '@CMAKE_TOOLCHAIN_FILE@'" + ) + endif() + set(_original_toolchain_file "@CMAKE_TOOLCHAIN_FILE@") + else() + set(_original_toolchain_file "@_INTERNAL_DEPTHAI_ORIGINAL_CMAKE_TOOLCHAIN_FILE@") + endif() + + set( + _INTERNAL_DEPTHAI_ORIGINAL_CMAKE_TOOLCHAIN_FILE + "${_original_toolchain_file}" + CACHE + PATH + "Original toolchain" + ) + + if("${_INTERNAL_DEPTHAI_ORIGINAL_CMAKE_TOOLCHAIN_FILE}" STREQUAL "${CMAKE_CURRENT_LIST_FILE}") + message(FATAL_ERROR "Internal error") + endif() + + set(ANDROID_NDK "") # Suppress warning + include("${_INTERNAL_DEPTHAI_ORIGINAL_CMAKE_TOOLCHAIN_FILE}") + +endif() + + +# STEP 3: Custom user variables + +if(NOT "@BUILD_SHARED_LIBS@" STREQUAL "") + # Simple PIC toolchain, which enables shared library building + # This option is propagated to 3rdparty dependecies as well + set(CMAKE_POSITION_INDEPENDENT_CODE ON) +endif() \ No newline at end of file diff --git a/bindings/python/cmake/toolchain/msvc.cmake b/bindings/python/cmake/toolchain/msvc.cmake new file mode 100644 index 000000000..9c5b41ce9 --- /dev/null +++ b/bindings/python/cmake/toolchain/msvc.cmake @@ -0,0 +1,5 @@ +# Set PIC +set(CMAKE_POSITION_INDEPENDENT_CODE ON) + +# Statically compile vcruntime library +add_compile_options(/MT) diff --git a/bindings/python/cmake/toolchain/pic.cmake b/bindings/python/cmake/toolchain/pic.cmake new file mode 100644 index 000000000..98689fc74 --- /dev/null +++ b/bindings/python/cmake/toolchain/pic.cmake @@ -0,0 +1,2 @@ +# Simple toolchain which enables PIC for all dependencies +set(CMAKE_POSITION_INDEPENDENT_CODE ON) \ No newline at end of file diff --git a/bindings/python/cmake/toolchain/tsan.cmake b/bindings/python/cmake/toolchain/tsan.cmake new file mode 100644 index 000000000..7af0a18f7 --- /dev/null +++ b/bindings/python/cmake/toolchain/tsan.cmake @@ -0,0 +1,12 @@ +set(_internal_flags_sanitizer "-fno-omit-frame-pointer -fsanitize=thread") +set(CMAKE_C_FLAGS ${_internal_flags_sanitizer}) +set(CMAKE_CXX_FLAGS ${_internal_flags_sanitizer}) +set(CMAKE_C_FLAGS_INIT ${_internal_flags_sanitizer}) +set(CMAKE_CXX_FLAGS_INIT ${_internal_flags_sanitizer}) +set(CMAKE_EXE_LINKER_FLAGS ${_internal_flags_sanitizer}) +set(CMAKE_EXE_LINKER_FLAGS_INIT ${_internal_flags_sanitizer}) +set(CMAKE_SHARED_LINKER_FLAGS ${_internal_flags_sanitizer}) +set(CMAKE_SHARED_LINKER_FLAGS_INIT ${_internal_flags_sanitizer}) +set(CMAKE_MODULE_LINKER_FLAGS ${_internal_flags_sanitizer}) +set(CMAKE_MODULE_LINKER_FLAGS_INIT ${_internal_flags_sanitizer}) +set(_internal_flags_sanitizer) \ No newline at end of file diff --git a/bindings/python/cmake/toolchain/ubsan.cmake b/bindings/python/cmake/toolchain/ubsan.cmake new file mode 100644 index 000000000..35231a380 --- /dev/null +++ b/bindings/python/cmake/toolchain/ubsan.cmake @@ -0,0 +1,12 @@ +set(_internal_flags_sanitizer "-fno-omit-frame-pointer -fsanitize=undefined") +set(CMAKE_C_FLAGS ${_internal_flags_sanitizer}) +set(CMAKE_CXX_FLAGS ${_internal_flags_sanitizer}) +set(CMAKE_C_FLAGS_INIT ${_internal_flags_sanitizer}) +set(CMAKE_CXX_FLAGS_INIT ${_internal_flags_sanitizer}) +set(CMAKE_EXE_LINKER_FLAGS ${_internal_flags_sanitizer}) +set(CMAKE_EXE_LINKER_FLAGS_INIT ${_internal_flags_sanitizer}) +set(CMAKE_SHARED_LINKER_FLAGS ${_internal_flags_sanitizer}) +set(CMAKE_SHARED_LINKER_FLAGS_INIT ${_internal_flags_sanitizer}) +set(CMAKE_MODULE_LINKER_FLAGS ${_internal_flags_sanitizer}) +set(CMAKE_MODULE_LINKER_FLAGS_INIT ${_internal_flags_sanitizer}) +set(_internal_flags_sanitizer) diff --git a/bindings/python/cmake/version.hpp.in b/bindings/python/cmake/version.hpp.in new file mode 100644 index 000000000..0316d6e6c --- /dev/null +++ b/bindings/python/cmake/version.hpp.in @@ -0,0 +1,24 @@ +/* + * Generated by CMake build tool. + * To modify version, open CMakeLists.txt and bump the version in project() function + */ +#pragma once + +namespace dai +{ +namespace build +{ + constexpr static const char* VERSION = "${PROJECT_VERSION}"; + constexpr static const int VERSION_MAJOR = ${PROJECT_VERSION_MAJOR}; + constexpr static const int VERSION_MINOR = ${PROJECT_VERSION_MINOR}; + constexpr static const int VERSION_PATCH = ${PROJECT_VERSION_PATCH}; + + constexpr static const char* COMMIT = "${BUILD_COMMIT}"; + constexpr static const char* COMMIT_DATETIME = "${BUILD_COMMIT_DATETIME}"; + constexpr static const char* BUILD_DATETIME = "${BUILD_DATETIME}"; + + constexpr static const char* DEVICE_VERSION = "${DEPTHAI_DEVICE_VERSION}"; + constexpr static const char* BOOTLOADER_VERSION = "${DEPTHAI_BOOTLOADER_VERSION}"; + constexpr static const char* DEVICE_RVC3_VERSION = "${DEPTHAI_DEVICE_RVC3_VERSION}"; +} // namespace build +} // namespace dai diff --git a/bindings/python/depthai_cli/__init__.py b/bindings/python/depthai_cli/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/bindings/python/depthai_cli/depthai_cli.py b/bindings/python/depthai_cli/depthai_cli.py new file mode 100644 index 000000000..e847a217e --- /dev/null +++ b/bindings/python/depthai_cli/depthai_cli.py @@ -0,0 +1,49 @@ +import os +from pathlib import Path +import subprocess + +here = os.path.dirname(os.path.realpath(__file__)) + +if os.path.exists(os.path.join(here, "cam_test.py")): # Installed package + CAM_TEST_PATH = Path(here) / "cam_test.py" +else: + CAM_TEST_PATH = ( + Path(here) / ".." / "utilities" / "cam_test.py" + ) # Execution from source +CAM_TEST_PATH = str(CAM_TEST_PATH) + + +def cli() -> int: + import argparse + import sys + import depthai as dai + parser = argparse.ArgumentParser(description="DepthAI CLI", add_help=True) + parser.add_argument("-v", "--version", action="store_true", help="Print version and exit.") + parser.add_argument("-l", "--list-devices", action="store_true", help="List connected devices.") + subparsers = parser.add_subparsers(dest="command", help="Sub-commands") + # Define the parser for the "cam_test" command + cam_test_parser = subparsers.add_parser("cam_test", help="Commands and options for cam_test", add_help=False) + cam_test_parser.add_argument("args", nargs=argparse.REMAINDER, help="Arguments to pass to cam_test") + + # subparser REMINDER args would get parsed too if we used parse_args, so we have to handle unknown args manually + args, unknown_args = parser.parse_known_args() + if args.command == "cam_test": + cam_test_path = CAM_TEST_PATH + return subprocess.run([sys.executable, cam_test_path] + cam_test_parser.parse_args().args[1:]).returncode + # Parse other subcommands here + elif unknown_args: + parser.error(f"Unrecognized arguments: {unknown_args}") # handles exit internally + elif args.version: + print(dai.__version__) + return 0 + elif args.list_devices: + print(dai.Device.getAllConnectedDevices()) + return 0 + else: + # No recognized commands, print help + parser.print_help() + return 1 + + +if __name__ == "__main__": + exit(cli()) diff --git a/bindings/python/docs/CMakeLists.txt b/bindings/python/docs/CMakeLists.txt new file mode 100644 index 000000000..6bc5a25ac --- /dev/null +++ b/bindings/python/docs/CMakeLists.txt @@ -0,0 +1,65 @@ +# This list specifies building of documentation using CMake + +# Specify path separator +set(SYS_PATH_SEPARATOR ";") +if(UNIX) + set(SYS_PATH_SEPARATOR ":") +endif() + +# Get doxygen build location form doxygen target +get_target_property(DOXYGEN_OUTPUT_DIR doxygen DOXYGEN_OUTPUT_DIR) +message(STATUS "Retrieved doxygen output dir from doxygen target: ${DOXYGEN_OUTPUT_DIR}") + +# Add input and output information for conf.py +set(SPHINX_SOURCE ${CMAKE_CURRENT_LIST_DIR}/source) +set(SPHINX_BUILD ${CMAKE_CURRENT_BINARY_DIR}/sphinx) + +# Add year information +string(TIMESTAMP build_year "%Y") +# Configure sphinx for the build +configure_file(conf.py.in "${CMAKE_CURRENT_BINARY_DIR}/conf.py" @ONLY) + +# Sphinx is required to build python documentation +# Find Python sphinx, by checking python -m sphinx +message(STATUS "Checking for sphinx") +execute_process(COMMAND ${PYTHON_EXECUTABLE} -m sphinx --version RESULT_VARIABLE error OUTPUT_QUIET ERROR_QUIET) +if(error) + set(message "Checking for sphinx - not found, target 'sphinx' not available") + if(NOT enforce) + message(STATUS ${message}) + else() + message(FATAL_ERROR ${message}) + endif() + # Exit + return() +else() + message(STATUS "Checking for sphinx - found, target 'sphinx' available") + + file(COPY ${SPHINX_SOURCE}/_static DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) + # Ready up sphinx - needed values configured in conf.py + add_custom_target(sphinx ALL + ${CMAKE_COMMAND} -E env + # Environment variables + # PATH (dlls) + "PATH=${HUNTER_INSTALL_PREFIX}/bin${SYS_PATH_SEPARATOR}$ENV{PATH}" + # Python path (to find compiled module) + "PYTHONPATH=$${SYS_PATH_SEPARATOR}$ENV{PYTHONPATH}" + # ASAN in case of sanitizers + "${ASAN_ENVIRONMENT_VARS}" + ############ SPHINX + ${PYTHON_EXECUTABLE} -m sphinx -c ${CMAKE_CURRENT_BINARY_DIR} -W --keep-going -b html ${SPHINX_SOURCE} ${SPHINX_BUILD} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Generating documentation with Sphinx" + VERBATIM + COMMAND_EXPAND_LISTS + ) + + # Add dependency to library + add_dependencies(sphinx ${TARGET_NAME}) + + # Add dependency to doxygen (C++) if exists + if(TARGET doxygen) + add_dependencies(sphinx doxygen) + endif() + +endif() diff --git a/bindings/python/docs/_extensions/zephyr/warnings_filter.py b/bindings/python/docs/_extensions/zephyr/warnings_filter.py new file mode 100644 index 000000000..650a76134 --- /dev/null +++ b/bindings/python/docs/_extensions/zephyr/warnings_filter.py @@ -0,0 +1,97 @@ +""" +Warnings filter extension +######################### + +Copyright (c) 2021 Nordic Semiconductor ASA +SPDX-License-Identifier: Apache-2.0 + +Introduction +============ + +This Sphinx plugin can be used to filter out warnings that are known to be false +positives. The warnings are filtered out based on a set of regular expressions +given via an configuration file. The format of the configuration file is a +plain-text file where each line consists of a regular expression. Any lines +starting with ``#`` will be ignored. + +Configuration options +===================== + +- ``warnings_filter_config``: Configuration file. +- ``warnings_filter_silent``: Silent flag. If True, warning is hidden. If False + the warning is converted to an information message and displayed. +""" + +import logging +import re +from typing import Dict, Any, List + +from sphinx.application import Sphinx +from sphinx.util.logging import NAMESPACE + + +__version__ = "0.1.0" + + +class WarningsFilter(logging.Filter): + """Warnings filter. + + Args: + expressions: List of regular expressions. + silent: If true, warning is hidden, otherwise it is shown as INFO. + name: Filter name. + """ + def __init__(self, expressions: List[str], silent: bool, name: str = "") -> None: + super().__init__(name) + + self._expressions = expressions + self._silent = silent + + def filter(self, record: logging.LogRecord) -> bool: + if record.levelno != logging.WARNING: + return True + + for expression in self._expressions: + if re.match(expression, record.msg): + if self._silent: + return False + else: + record.levelno = logging.INFO + record.msg = f"Filtered warning: {record.msg}" + return True + + return True + + +def configure(app: Sphinx) -> None: + """Entry point. + + Args: + app: Sphinx application instance. + """ + + # load expressions from configuration file + with open(app.config.warnings_filter_config) as f: + expressions = list() + for line in f.readlines(): + if not line.startswith("#"): + expressions.append(line.rstrip()) + + # install warnings filter to all the Sphinx logger handlers + filter = WarningsFilter(expressions, app.config.warnings_filter_silent) + logger = logging.getLogger(NAMESPACE) + for handler in logger.handlers: + handler.filters.insert(0, filter) + + +def setup(app: Sphinx) -> Dict[str, Any]: + app.add_config_value("warnings_filter_config", "", "") + app.add_config_value("warnings_filter_silent", True, "") + + app.connect("builder-inited", configure) + + return { + "version": __version__, + "parallel_read_safe": True, + "parallel_write_safe": True, + } diff --git a/bindings/python/docs/ci.cmake b/bindings/python/docs/ci.cmake new file mode 100644 index 000000000..16708b844 --- /dev/null +++ b/bindings/python/docs/ci.cmake @@ -0,0 +1,19 @@ +# Builds library at 'build/' and prepares sphinx configuration at 'build/docs/conf.py' +set(project_root "${CMAKE_CURRENT_LIST_DIR}/..") + +# Get buildCommitHash for non release build +execute_process(COMMAND "git" "rev-parse" "HEAD" WORKING_DIRECTORY ${project_root} OUTPUT_VARIABLE buildCommitHash OUTPUT_STRIP_TRAILING_WHITESPACE) + +# Configure +execute_process(COMMAND ${CMAKE_COMMAND} + -D DEPTHAI_PYTHON_COMMIT_HASH:STRING=${buildCommitHash} + -D DEPTHAI_PYTHON_BUILD_DOCS:BOOL=YES + -D DEPTHAI_BUILD_DOCS:BOOL=YES + -D DEPTHAI_PYTHON_BUILD_DOCSTRINGS:BOOL=YES + -D DEPTHAI_PYTHON_FORCE_DOCSTRINGS:BOOL=YES + -S . -B build + WORKING_DIRECTORY ${project_root} COMMAND_ECHO STDOUT +) + +# Build +execute_process(COMMAND ${CMAKE_COMMAND} --build build --parallel 2 WORKING_DIRECTORY ${project_root} COMMAND_ECHO STDOUT) \ No newline at end of file diff --git a/bindings/python/docs/conf.py.in b/bindings/python/docs/conf.py.in new file mode 100644 index 000000000..1c057d961 --- /dev/null +++ b/bindings/python/docs/conf.py.in @@ -0,0 +1,113 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# + +import os +import sys +from pathlib import Path + +source_directory = Path('@SPHINX_SOURCE@') + +# Add path to built module +sys.path.insert(0, os.path.abspath('@CMAKE_BINARY_DIR@')) + +# Add _extensions +sys.path.insert(0, os.path.abspath(source_directory / ".." / "_extensions")) + +# -- Project information ----------------------------------------------------- + +project = "DepthAI API Docs" +html_show_copyright=False +author = "Luxonis" +version = u"@DEPTHAI_PYTHON_VERSION@" +release = version +pypi_release = "2.0.0.1" + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + "sphinx_tabs.tabs", + "sphinx-prompt", 'sphinx_substitution_extensions', # Substitute certain variables inside code blocks + "breathe", # Generate sphinx documentation from doxygen + "sphinx.ext.autodoc", # Generate documentation from python module + "sphinx.ext.napoleon", + "autodocsumm", + "sphinx.ext.viewcode", + "sphinx.ext.intersphinx", + "sphinx.ext.autosectionlabel", # https://github.com/sphinx-doc/sphinx/issues/7697 wait for this and implement + "sphinx_rtd_theme", + "zephyr.warnings_filter", + 'sphinx.ext.mathjax', +] + +# See https://github.com/sphinx-doc/sphinx/issues/7728 +suppress_warnings = ['autosectionlabel.*'] + +# # Debug docstrings +# def autodoc_process_docstring(app, what, name, obj, options, lines): +# print('process: ', what, name, obj, options, lines) +# def setup(app): +# app.connect("autodoc-process-docstring", autodoc_process_docstring) + +# substitutions +rst_prolog = '.. |release| replace:: ' + release + +# Breathe Configuration +# Project name depthai-core -> path to doxygen generated by + +# Check if we're running on Read the Docs' servers (set path to generate doxygen manually) +breathe_projects = {"depthai-core": "@DOXYGEN_OUTPUT_DIR@/xml"} +# Set depthai-core as default breathe project +breathe_default_project = "depthai-core" + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = [] + +# -- Options for zephyr.warnings_filter ----------------------------------- +warnings_filter_config = str(source_directory / ".." / "known-warnings.txt") +warnings_filter_silent = False + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'sphinx_rtd_theme' + +html_theme_options = { + "collapse_navigation" : False +} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] +html_favicon = '_static/images/favicon.png' +html_css_files = [ + 'css/index.css', + 'https://docs.luxonis.com/en/latest/_static/css/navbar.css', +] +html_js_files = [ + 'https://docs.luxonis.com/en/latest/_static/js/navbar.js', +] +html_title = 'DepthAI documentation | Luxonis' + +intersphinx_mapping = {'python': ('https://docs.python.org/3', None)} diff --git a/bindings/python/docs/docker-compose.yml b/bindings/python/docs/docker-compose.yml new file mode 100644 index 000000000..dc27094a3 --- /dev/null +++ b/bindings/python/docs/docker-compose.yml @@ -0,0 +1,10 @@ +version: "3" +services: + docs: + build: + dockerfile: docs/docker/dev.dockerfile + context: .. + volumes: + - ./:/app/docs + ports: + - 8000:8000 diff --git a/bindings/python/docs/docker/dev.dockerfile b/bindings/python/docs/docker/dev.dockerfile new file mode 100644 index 000000000..1054de6d4 --- /dev/null +++ b/bindings/python/docs/docker/dev.dockerfile @@ -0,0 +1,14 @@ +FROM ubuntu:20.04 + +ARG DEBIAN_FRONTEND=noninteractive +RUN apt-get update && apt-get install -y libusb-1.0-0-dev clang python3-opencv python3-pip clang-11 doxygen graphviz cmake git +RUN python3 -m pip install -U pip numpy when-changed + +ENV CC clang-10 +ENV CXX clang++-10 +WORKDIR /app +ADD docs/requirements.txt docs/requirements.txt +ADD docs/requirements_mkdoc.txt docs/requirements_mkdoc.txt +RUN python3 -m pip install -r docs/requirements.txt +ADD . . +CMD docs/docker/docker_run.sh diff --git a/bindings/python/docs/docker/docker_run.sh b/bindings/python/docs/docker/docker_run.sh new file mode 100755 index 000000000..7e1dc0361 --- /dev/null +++ b/bindings/python/docs/docker/docker_run.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -e + +cmake -S . -B build -D DEPTHAI_BUILD_DOCS=ON -D DEPTHAI_PYTHON_BUILD_DOCS=ON + +./docs/docker/update_docs.sh + +when-changed -r docs/source -c "bash /app/docs/docker/update_docs.sh" & + +python3 -m http.server --bind 0.0.0.0 8000 --directory build/docs/sphinx diff --git a/bindings/python/docs/docker/update_docs.sh b/bindings/python/docs/docker/update_docs.sh new file mode 100755 index 000000000..87783a886 --- /dev/null +++ b/bindings/python/docs/docker/update_docs.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +set -e + +cmake --build build --target doxygen sphinx --parallel diff --git a/bindings/python/docs/known-warnings.txt b/bindings/python/docs/known-warnings.txt new file mode 100644 index 000000000..c787dcbba --- /dev/null +++ b/bindings/python/docs/known-warnings.txt @@ -0,0 +1,8 @@ +# Each line should contain the regular expression of a known Sphinx warning +# that should be filtered out +.*Duplicate C\+\+ declaration.*\n.*'\.\. cpp:class::.*dai::ADatatype'.* +.*Duplicate C\+\+ declaration.*\n.*'\.\. cpp:class::.*dai::Buffer'.* +.*Duplicate C\+\+ declaration, also defined at components/nodes/.* +.*Duplicate C\+\+ declaration, also defined at components/messages/.* +.*Duplicate C\+\+ declaration, also defined at components/pipeline.* +.*Duplicate C\+\+ declaration, also defined at components/device.* \ No newline at end of file diff --git a/bindings/python/docs/readthedocs/requirements.txt b/bindings/python/docs/readthedocs/requirements.txt new file mode 100644 index 000000000..41dc790fd --- /dev/null +++ b/bindings/python/docs/readthedocs/requirements.txt @@ -0,0 +1,2 @@ +cmake==3.17.3 +-r ../requirements.txt diff --git a/bindings/python/docs/redirects.yml b/bindings/python/docs/redirects.yml new file mode 100644 index 000000000..8f0b4f3c1 --- /dev/null +++ b/bindings/python/docs/redirects.yml @@ -0,0 +1,193 @@ +# To update redirects on the page, please use +# +# ``` +# rtd-redirects luxonis-depthai-python ./redirects.yml --pro --username --password +# ``` +# +# Username and password are the credentials you use to access the RTD website +# +# **You need to have sufficient privileges on the RTD to change the redirects** + +redirects: + "/samples/autoexposure_roi/": "/samples/ColorCamera/autoexposure_roi/" + "/samples/bootloader_config/": "/samples/bootloader/bootloader_config/" + "/samples/bootloader_version/": "/samples/bootloader/bootloader_version/" + "/samples/calibration_flash/": "/samples/calibration/calibration_flash/" + "/samples/calibration_flash_v5/": "/samples/calibration/calibration_flash_v5/" + "/samples/calibration_load/": "/samples/calibration/calibration_load/" + "/samples/calibration_reader/": "/samples/calibration/calibration_reader/" + "/samples/corner_detector/": "/samples/FeatureTracker/corner_detector/" + "/samples/depth_crop_control/": "/samples/StereoDepth/depth_crop_control/" + "/samples/depth_preview/": "/samples/StereoDepth/depth_preview/" + "/samples/device_queue_event/": "/samples/host_side/device_queue_event/" + "/samples/edge_detector/": "/samples/EdgeDetector/edge_detector/" + "/samples/encoding_max_limit/": "/samples/VideoEncoder/encoding_max_limit/" + "/samples/feature_tracker/": "/samples/FeatureTracker/feature_tracker/" + "/samples/flash_bootloader/": "/samples/bootloader/flash_bootloader/" + "/samples/image_manip_rotate/": "/samples/ImageManip/image_manip_rotate/" + "/samples/image_manip_tiling/": "/samples/ImageManip/image_manip_tiling/" + "/samples/imu_gyroscope_accelerometer/": "/samples/IMU/imu_gyroscope_accelerometer/" + "/samples/imu_rotation_vector/": "/samples/IMU/imu_rotation_vector/" + "/samples/mono_camera_control/": "/samples/MonoCamera/mono_camera_control/" + "/samples/mono_depth_mobilenetssd/": "/samples/mixed/mono_depth_mobilenetssd/" + "/samples/mono_full_resolution_saver/": "/samples/MonoCamera/mono_full_resolution_saver/" + "/samples/mono_mobilenet/": "/samples/MobileNet/mono_mobilenet/" + "/samples/mono_preview/": "/samples/MonoCamera/mono_preview/" + "/samples/object_tracker/": "/samples/ObjectTracker/object_tracker/" + "/samples/object_tracker_video/": "/samples/ObjectTracker/object_tracker_video/" + "/samples/opencv_support/": "/samples/host_side/opencv_support/" + "/samples/queue_add_callback/": "/samples/host_side/queue_add_callback/" + "/samples/rgb_camera_control/": "/samples/ColorCamera/rgb_camera_control/" + "/samples/rgb_depth_aligned/": "/samples/StereoDepth/rgb_depth_aligned/" + "/samples/rgb_encoding/": "/samples/VideoEncoder/rgb_encoding/" + "/samples/rgb_encoding_mobilenet/": "/samples/mixed/rgb_encoding_mobilenet/" + "/samples/rgb_encoding_mono_mobilenet/": "/samples/mixed/rgb_encoding_mono_mobilenet/" + "/samples/rgb_encoding_mono_mobilenet_depth/": "/samples/mixed/rgb_encoding_mono_mobilenet_depth/" + "/samples/rgb_full_resolution_saver/": "/samples/VideoEncoder/rgb_full_resolution_saver/" + "/samples/rgb_mobilenet/": "/samples/MobileNet/rgb_mobilenet/" + "/samples/rgb_mobilenet_4k/": "/samples/MobileNet/rgb_mobilenet_4k/" + "/samples/rgb_mono_encoding/": "/samples/VideoEncoder/rgb_mono_encoding/" + "/samples/rgb_preview/": "/samples/ColorCamera/rgb_preview/" + "/samples/rgb_rotate_warp/": "/samples/ImageManip/rgb_rotate_warp/" + "/samples/rgb_video/": "/samples/ColorCamera/rgb_video/" + "/samples/script_camera_control/": "/samples/Script/script_camera_control/" + "/samples/spatial_location_calculator/": "/samples/SpatialDetection/spatial_location_calculator/" + "/samples/spatial_mobilenet/": "/samples/SpatialDetection/spatial_mobilenet/" + "/samples/spatial_mobilenet_mono/": "/samples/SpatialDetection/spatial_mobilenet_mono/" + "/samples/spatial_object_tracker/": "/samples/ObjectTracker/spatial_object_tracker/" + "/samples/spatial_tiny_yolo/": "/samples/SpatialDetection/spatial_tiny_yolo/" + "/samples/stereo_depth_from_host/": "/samples/StereoDepth/stereo_depth_from_host/" + "/samples/stereo_depth_video/": "/samples/StereoDepth/stereo_depth_video/" + "/samples/system_information/": "/samples/SystemLogger/system_information/" + "/samples/tiny_yolo_v3_device_side_decoding/": "/samples/Yolo/tiny_yolo/" + "/samples/tiny_yolo_v4_device_side_decoding/": "/samples/Yolo/tiny_yolo/" + "/samples/video_mobilenet/": "/samples/MobileNet/video_mobilenet/" + "/samples/30_stereo_depth_from_host/": "/samples/StereoDepth/stereo_depth_from_host/" + "/samples/29_3_object_tracker_video/": "/samples/ObjectTracker/object_tracker_video/" + "/samples/29_2_spatial_object_tracker/": "/samples/ObjectTracker/spatial_object_tracker/" + "/samples/29_1_object_tracker/": "/samples/ObjectTracker/object_tracker/" + "/samples/28_camera_video_example/": "/samples/ColorCamera/rgb_video/" + "/samples/27_spatial_location_calculator/": "/samples/SpatialDetection/spatial_location_calculator/" + "/samples/26_3_spatial_tiny_yolo/": "/samples/SpatialDetection/spatial_tiny_yolo/" + "/samples/26_2_spatial_mobilenet_mono/": "/samples/SpatialDetection/spatial_mobilenet_mono/" + "/samples/26_1_spatial_mobilenet/": "/samples/SpatialDetection/spatial_mobilenet/" + "/samples/25_system_information/": "/samples/SystemLogger/system_information/" + "/samples/24_opencv_support/": "/samples/host_side/opencv_support/" + "/samples/23_autoexposure_roi/": "/samples/ColorCamera/autoexposure_roi/" + "/samples/22_2_tiny_yolo_v4_decoding_on_device/": "/samples/Yolo/tiny_yolo/" + "/samples/22_1_tiny_yolo_v3_decoding_on_device/": "/samples/Yolo/tiny_yolo/" + "/samples/20_color_rotate_warp/": "/samples/ImageManip/rgb_rotate_warp/" + "/samples/19_mono_camera_control/": "/samples/MonoCamera/mono_camera_control/" + "/samples/18_rgb_encoding_mobilenet/": "/samples/mixed/rgb_encoding_mobilenet/" + "/samples/17_video_mobilenet/": "/samples/MobileNet/video_mobilenet/" + "/samples/16_device_queue_event/": "/samples/host_side/device_queue_event/" + "/samples/15_rgb_mobilenet_4k/": "/samples/MobileNet/rgb_mobilenet_4k/" + "/samples/14_3_depth_crop_control/": "/samples/StereoDepth/depth_crop_control/" + "/samples/14_2_mono_camera_control/": "/samples/MonoCamera/mono_camera_control/" + "/samples/14_1_color_camera_control/": "/samples/ColorCamera/rgb_camera_control/" + "/samples/13_encoding_max_limit/": "/samples/VideoEncoder/encoding_max_limit/" + "/samples/11_rgb_encoding_mono_mobilenet/": "/samples/mixed/rgb_encoding_mono_mobilenet/" + "/samples/12_rgb_encoding_mono_mobilenet_depth/": "/samples/mixed/rgb_encoding_mono_mobilenet_depth/" + "/samples/10_mono_depth_mobilenetssd/": "/samples/mixed/mono_depth_mobilenetssd/" + "/samples/09_mono_mobilenet/": "/samples/MobileNet/mono_mobilenet/" + "/samples/08_rgb_mobilenet/": "/samples/MobileNet/rgb_mobilenet/" + "/samples/07_mono_full_resolution_saver/": "/samples/MonoCamera/mono_full_resolution_saver/" + "/samples/06_rgb_full_resolution_saver/": "/samples/VideoEncoder/rgb_full_resolution_saver/" + "/samples/05_rgb_mono_encoding/": "/samples/VideoEncoder/rgb_mono_encoding/" + "/samples/04_rgb_encoding/": "/samples/VideoEncoder/rgb_encoding/" + "/samples/03_depth_preview/": "/samples/StereoDepth/depth_preview/" + "/samples/02_mono_preview/": "/samples/MonoCamera/mono_preview/" + "/samples/01_rgb_preview/": "/samples/ColorCamera/rgb_preview/" + "/samples/14_color_camera_control/": "/samples/ColorCamera/rgb_camera_control/" + "/samples/21_mobilenet_decoding_on_device/": "/samples/MobileNet/rgb_mobilenet/" + "/samples/autoexposure_roi": "/samples/ColorCamera/autoexposure_roi/" + "/samples/bootloader_config": "/samples/bootloader/bootloader_config/" + "/samples/bootloader_version": "/samples/bootloader/bootloader_version/" + "/samples/calibration_flash": "/samples/calibration/calibration_flash/" + "/samples/calibration_flash_v5": "/samples/calibration/calibration_flash_v5/" + "/samples/calibration_load": "/samples/calibration/calibration_load/" + "/samples/calibration_reader": "/samples/calibration/calibration_reader/" + "/samples/corner_detector": "/samples/FeatureTracker/corner_detector/" + "/samples/depth_crop_control": "/samples/StereoDepth/depth_crop_control" + "/samples/depth_preview": "/samples/StereoDepth/depth_preview/" + "/samples/device_queue_event": "/samples/host_side/device_queue_event/" + "/samples/edge_detector": "/samples/EdgeDetector/edge_detector/" + "/samples/encoding_max_limit": "/samples/VideoEncoder/encoding_max_limit/" + "/samples/feature_tracker": "/samples/FeatureTracker/feature_tracker/" + "/samples/flash_bootloader": "/samples/bootloader/flash_bootloader/" + "/samples/image_manip_rotate": "/samples/ImageManip/image_manip_rotate/" + "/samples/image_manip_tiling": "/samples/ImageManip/image_manip_tiling/" + "/samples/imu_gyroscope_accelerometer": "/samples/IMU/imu_gyroscope_accelerometer/" + "/samples/imu_rotation_vector": "/samples/IMU/imu_rotation_vector" + "/samples/mono_camera_control": "/samples/MonoCamera/mono_camera_control/" + "/samples/mono_depth_mobilenetssd": "/samples/mixed/mono_depth_mobilenetssd/" + "/samples/mono_full_resolution_saver": "/samples/MonoCamera/mono_full_resolution_saver/" + "/samples/mono_mobilenet": "/samples/MobileNet/mono_mobilenet/" + "/samples/mono_preview": "/samples/MonoCamera/mono_preview/" + "/samples/object_tracker": "//samples/ObjectTracker/object_tracker/" + "/samples/object_tracker_video": "/samples/ObjectTracker/object_tracker_video/" + "/samples/opencv_support": "/samples/host_side/opencv_support/" + "/samples/queue_add_callback": "/samples/host_side/queue_add_callback/" + "/samples/rgb_camera_control": "/samples/ColorCamera/rgb_camera_control/" + "/samples/rgb_depth_aligned": "/samples/StereoDepth/rgb_depth_aligned/" + "/samples/rgb_encoding": "/samples/VideoEncoder/rgb_encoding/" + "/samples/rgb_encoding_mobilenet": "/samples/mixed/rgb_encoding_mobilenet/" + "/samples/rgb_encoding_mono_mobilenet": "/samples/mixed/rgb_encoding_mono_mobilenet/" + "/samples/rgb_encoding_mono_mobilenet_depth": "/samples/mixed/rgb_encoding_mono_mobilenet_depth/" + "/samples/rgb_full_resolution_saver": "/samples/VideoEncoder/rgb_full_resolution_saver/" + "/samples/rgb_mobilenet": "/samples/MobileNet/rgb_mobilenet/" + "/samples/rgb_mobilenet_4k": "/samples/MobileNet/rgb_mobilenet_4k/" + "/samples/rgb_mono_encoding": "/samples/VideoEncoder/rgb_mono_encoding/" + "/samples/rgb_preview": "/samples/ColorCamera/rgb_preview/" + "/samples/rgb_rotate_warp": "/samples/ImageManip/rgb_rotate_warp/" + "/samples/rgb_video": "/samples/ColorCamera/rgb_video/" + "/samples/script_camera_control": "/samples/Script/script_camera_control/" + "/samples/spatial_location_calculator": "/samples/SpatialDetection/spatial_location_calculator/" + "/samples/spatial_mobilenet": "/samples/SpatialDetection/spatial_mobilenet/" + "/samples/spatial_mobilenet_mono": "/samples/SpatialDetection/spatial_mobilenet_mono/" + "/samples/spatial_object_tracker": "/samples/ObjectTracker/spatial_object_tracker/" + "/samples/spatial_tiny_yolo": "/samples/SpatialDetection/spatial_tiny_yolo/" + "/samples/stereo_depth_from_host": "/samples/StereoDepth/stereo_depth_from_host/" + "/samples/stereo_depth_video": "/samples/StereoDepth/stereo_depth_video/" + "/samples/system_information": "/samples/SystemLogger/system_information/" + "/samples/tiny_yolo_v3_device_side_decoding": "/samples/Yolo/tiny_yolo/" + "/samples/tiny_yolo_v4_device_side_decoding": "/samples/Yolo/tiny_yolo/" + "/samples/video_mobilenet": "/samples/MobileNet/video_mobilenet/" + "/samples/30_stereo_depth_from_host": "/samples/StereoDepth/stereo_depth_from_host/" + "/samples/29_3_object_tracker_video": "/samples/ObjectTracker/object_tracker_video/" + "/samples/29_2_spatial_object_tracker": "/samples/ObjectTracker/spatial_object_tracker/" + "/samples/29_1_object_tracker": "/samples/ObjectTracker/object_tracker/" + "/samples/28_camera_video_example": "/samples/ColorCamera/rgb_video/" + "/samples/27_spatial_location_calculator": "/samples/SpatialDetection/spatial_location_calculator/" + "/samples/26_3_spatial_tiny_yolo": "/samples/SpatialDetection/spatial_tiny_yolo/" + "/samples/26_2_spatial_mobilenet_mono": "/samples/SpatialDetection/spatial_mobilenet_mono/" + "/samples/26_1_spatial_mobilenet": "/samples/SpatialDetection/spatial_mobilenet/" + "/samples/25_system_information": "/samples/SystemLogger/system_information/" + "/samples/24_opencv_support": "/samples/host_side/opencv_support/" + "/samples/23_autoexposure_roi": "/samples/ColorCamera/autoexposure_roi/" + "/samples/22_2_tiny_yolo_v4_decoding_on_device": "/samples/Yolo/tiny_yolo/" + "/samples/22_1_tiny_yolo_v3_decoding_on_device": "/samples/Yolo/tiny_yolo/" + "/samples/20_color_rotate_warp": "/samples/ImageManip/rgb_rotate_warp/" + "/samples/19_mono_camera_control": "/samples/MonoCamera/mono_camera_control/" + "/samples/18_rgb_encoding_mobilenet": "/samples/mixed/rgb_encoding_mobilenet/" + "/samples/17_video_mobilenet": "/samples/MobileNet/video_mobilenet/" + "/samples/16_device_queue_event": "/samples/host_side/device_queue_event/" + "/samples/15_rgb_mobilenet_4k": "/samples/MobileNet/rgb_mobilenet_4k/" + "/samples/14_3_depth_crop_control": "/samples/StereoDepth/depth_crop_control" + "/samples/14_2_mono_camera_control": "/samples/MonoCamera/mono_camera_control/" + "/samples/14_1_color_camera_control": "/samples/ColorCamera/rgb_camera_control/" + "/samples/13_encoding_max_limit": "/samples/VideoEncoder/encoding_max_limit/" + "/samples/11_rgb_encoding_mono_mobilenet": "/samples/mixed/rgb_encoding_mono_mobilenet/" + "/samples/12_rgb_encoding_mono_mobilenet_depth": "/samples/mixed/rgb_encoding_mono_mobilenet_depth/" + "/samples/10_mono_depth_mobilenetssd": "/samples/mixed/mono_depth_mobilenetssd/" + "/samples/09_mono_mobilenet": "/samples/MobileNet/mono_mobilenet/" + "/samples/08_rgb_mobilenet": "/samples/MobileNet/rgb_mobilenet/" + "/samples/07_mono_full_resolution_saver": "/samples/MonoCamera/mono_full_resolution_saver/" + "/samples/06_rgb_full_resolution_saver": "/samples/VideoEncoder/rgb_full_resolution_saver/" + "/samples/05_rgb_mono_encoding": "/samples/VideoEncoder/rgb_mono_encoding/" + "/samples/04_rgb_encoding": "/samples/VideoEncoder/rgb_encoding/" + "/samples/03_depth_preview": "/samples/StereoDepth/depth_preview/" + "/samples/02_mono_preview": "/samples/MonoCamera/mono_preview/" + "/samples/01_rgb_preview": "/samples/ColorCamera/rgb_preview/" + "/samples/14_color_camera_control": "/samples/ColorCamera/rgb_camera_control/" + "/samples/21_mobilenet_decoding_on_device": "/samples/MobileNet/rgb_mobilenet/" \ No newline at end of file diff --git a/bindings/python/docs/requirements.txt b/bindings/python/docs/requirements.txt new file mode 100644 index 000000000..680df7b44 --- /dev/null +++ b/bindings/python/docs/requirements.txt @@ -0,0 +1,12 @@ +Sphinx==3.4.3 +sphinx-tabs==1.3.0 +sphinx-rtd-theme==0.5.2 +git+https://github.com/VanDavv/rtd-redirects.git@3e7333898acad533b37c9de426f1f2ef258d756b +breathe==4.26.0 +Sphinx-Substitution-Extensions==2020.9.30.0 +sphinx-autopackagesummary==1.3 +autodocsumm==0.2.2 +pathlib==1.0.1 +jinja2==3.0.3 +urllib3==1.26.15 # New urllib version breaks sphinx +-r ./requirements_mkdoc.txt diff --git a/bindings/python/docs/requirements_mkdoc.txt b/bindings/python/docs/requirements_mkdoc.txt new file mode 100644 index 000000000..c823ac6cc --- /dev/null +++ b/bindings/python/docs/requirements_mkdoc.txt @@ -0,0 +1,3 @@ +git+https://github.com/luxonis/pybind11_mkdoc.git@da6c64251a0ebbc3ffc007477a0b9c9f20cac165 +libclang==16.0.6 +numpy # Needed because of xtensor-python diff --git a/bindings/python/docs/source/_static/css/index.css b/bindings/python/docs/source/_static/css/index.css new file mode 100644 index 000000000..393d50c70 --- /dev/null +++ b/bindings/python/docs/source/_static/css/index.css @@ -0,0 +1,107 @@ +/* Additional styles or overrides */ + +h5 { + margin-bottom: 5%; +} + +.items-row { + display: flex; + margin-bottom: 5%; +} + +video { + max-width: 100%; +} + +.items-col { + width: 50% +} + +.item { + height: 100%; + padding: 0 15px; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.item .item-img-wrapper { + height: 200px; + margin-bottom: 10px; + text-align: center; +} + +.item .item-img-wrapper .item-img { + max-height: 100%; + max-width: 100%; +} + +.item .item-body { + flex-grow: 5; +} + +.item .item-cta { + width: 100%; +} + +.cta-row { + display: flex; + justify-content: space-between; + margin-bottom: 20px; +} + +.cta-row .cta-box { + width: 33%; + margin: 0 5px; + padding: 10px; + border: 1px solid rgba(0,0,0,.125); + border-radius: 10px; +} + +.cta-row .cta-box img { + width: 24px; + height: 24px; + margin-right: 10px; +} + +.cta-row .cta-box a { + display: flex; +} + +@media (max-width: 1000px) { + .cta-row { + flex-direction: column; + align-items: center; + } + .cta-row .cta-box { + margin: 5px 0; + width: 250px; + } +} + +@media (min-width: 600px) and (max-width: 1000px) { + .item .item-img-wrapper { + height: 150px; + } +} + +@media (min-width: 400px) and (max-width: 600px) { + .item .item-img-wrapper { + height: 100px; + } +} + +@media (max-width: 400px) { + .item .item-img-wrapper { + height: 50px; + } +} + +.wy-side-nav-search { + background-color: #004d80; +} + +.cta-row-short h5 { + margin-bottom: 0; +} + diff --git a/bindings/python/docs/source/_static/images/api_diagram.png b/bindings/python/docs/source/_static/images/api_diagram.png new file mode 100644 index 000000000..9f26a4d38 Binary files /dev/null and b/bindings/python/docs/source/_static/images/api_diagram.png differ diff --git a/bindings/python/docs/source/_static/images/components/Euclidian_distance_fig.png b/bindings/python/docs/source/_static/images/components/Euclidian_distance_fig.png new file mode 100644 index 000000000..67dca5303 Binary files /dev/null and b/bindings/python/docs/source/_static/images/components/Euclidian_distance_fig.png differ diff --git a/bindings/python/docs/source/_static/images/components/boot-depthai.jpeg b/bindings/python/docs/source/_static/images/components/boot-depthai.jpeg new file mode 100644 index 000000000..cc786da14 Binary files /dev/null and b/bindings/python/docs/source/_static/images/components/boot-depthai.jpeg differ diff --git a/bindings/python/docs/source/_static/images/components/clock-syncing.png b/bindings/python/docs/source/_static/images/components/clock-syncing.png new file mode 100644 index 000000000..7717c3af4 Binary files /dev/null and b/bindings/python/docs/source/_static/images/components/clock-syncing.png differ diff --git a/bindings/python/docs/source/_static/images/components/depth_diagram.png b/bindings/python/docs/source/_static/images/components/depth_diagram.png new file mode 100644 index 000000000..a45405433 Binary files /dev/null and b/bindings/python/docs/source/_static/images/components/depth_diagram.png differ diff --git a/bindings/python/docs/source/_static/images/components/device_timesync.jpg b/bindings/python/docs/source/_static/images/components/device_timesync.jpg new file mode 100644 index 000000000..115ef5ffb Binary files /dev/null and b/bindings/python/docs/source/_static/images/components/device_timesync.jpg differ diff --git a/bindings/python/docs/source/_static/images/components/disp_to_depth.jpg b/bindings/python/docs/source/_static/images/components/disp_to_depth.jpg new file mode 100644 index 000000000..c5bda25f5 Binary files /dev/null and b/bindings/python/docs/source/_static/images/components/disp_to_depth.jpg differ diff --git a/bindings/python/docs/source/_static/images/components/disparity_confidence.jpg b/bindings/python/docs/source/_static/images/components/disparity_confidence.jpg new file mode 100644 index 000000000..3d8d4b3b4 Binary files /dev/null and b/bindings/python/docs/source/_static/images/components/disparity_confidence.jpg differ diff --git a/bindings/python/docs/source/_static/images/components/disparity_explanation.jpeg b/bindings/python/docs/source/_static/images/components/disparity_explanation.jpeg new file mode 100644 index 000000000..e5450fd20 Binary files /dev/null and b/bindings/python/docs/source/_static/images/components/disparity_explanation.jpeg differ diff --git a/bindings/python/docs/source/_static/images/components/disparity_shift.png b/bindings/python/docs/source/_static/images/components/disparity_shift.png new file mode 100644 index 000000000..83a3b5ee5 Binary files /dev/null and b/bindings/python/docs/source/_static/images/components/disparity_shift.png differ diff --git a/bindings/python/docs/source/_static/images/components/http_server.png b/bindings/python/docs/source/_static/images/components/http_server.png new file mode 100644 index 000000000..ae868db63 Binary files /dev/null and b/bindings/python/docs/source/_static/images/components/http_server.png differ diff --git a/bindings/python/docs/source/_static/images/components/pointcloud_layering.jpg b/bindings/python/docs/source/_static/images/components/pointcloud_layering.jpg new file mode 100644 index 000000000..554816e8d Binary files /dev/null and b/bindings/python/docs/source/_static/images/components/pointcloud_layering.jpg differ diff --git a/bindings/python/docs/source/_static/images/components/spatial-coordinates.png b/bindings/python/docs/source/_static/images/components/spatial-coordinates.png new file mode 100644 index 000000000..7aaaf3c6e Binary files /dev/null and b/bindings/python/docs/source/_static/images/components/spatial-coordinates.png differ diff --git a/bindings/python/docs/source/_static/images/components/theoretical_error.jpg b/bindings/python/docs/source/_static/images/components/theoretical_error.jpg new file mode 100644 index 000000000..9b71d37a5 Binary files /dev/null and b/bindings/python/docs/source/_static/images/components/theoretical_error.jpg differ diff --git a/bindings/python/docs/source/_static/images/examples/depth_comparison.png b/bindings/python/docs/source/_static/images/examples/depth_comparison.png new file mode 100644 index 000000000..33ef4ba61 Binary files /dev/null and b/bindings/python/docs/source/_static/images/examples/depth_comparison.png differ diff --git a/bindings/python/docs/source/_static/images/examples/depth_video_synced.gif b/bindings/python/docs/source/_static/images/examples/depth_video_synced.gif new file mode 100644 index 000000000..1c37fd5e3 Binary files /dev/null and b/bindings/python/docs/source/_static/images/examples/depth_video_synced.gif differ diff --git a/bindings/python/docs/source/_static/images/examples/edge_detections.png b/bindings/python/docs/source/_static/images/examples/edge_detections.png new file mode 100644 index 000000000..587fec393 Binary files /dev/null and b/bindings/python/docs/source/_static/images/examples/edge_detections.png differ diff --git a/bindings/python/docs/source/_static/images/examples/feature_detector.png b/bindings/python/docs/source/_static/images/examples/feature_detector.png new file mode 100644 index 000000000..52c21e9c9 Binary files /dev/null and b/bindings/python/docs/source/_static/images/examples/feature_detector.png differ diff --git a/bindings/python/docs/source/_static/images/examples/feature_motion_estimation.gif b/bindings/python/docs/source/_static/images/examples/feature_motion_estimation.gif new file mode 100644 index 000000000..97819cce3 Binary files /dev/null and b/bindings/python/docs/source/_static/images/examples/feature_motion_estimation.gif differ diff --git a/bindings/python/docs/source/_static/images/examples/normalize_model.png b/bindings/python/docs/source/_static/images/examples/normalize_model.png new file mode 100644 index 000000000..be861497a Binary files /dev/null and b/bindings/python/docs/source/_static/images/examples/normalize_model.png differ diff --git a/bindings/python/docs/source/_static/images/examples/scene.png b/bindings/python/docs/source/_static/images/examples/scene.png new file mode 100644 index 000000000..4b728db7c Binary files /dev/null and b/bindings/python/docs/source/_static/images/examples/scene.png differ diff --git a/bindings/python/docs/source/_static/images/favicon.png b/bindings/python/docs/source/_static/images/favicon.png new file mode 100644 index 000000000..decd05d31 Binary files /dev/null and b/bindings/python/docs/source/_static/images/favicon.png differ diff --git a/bindings/python/docs/source/_static/images/references/centerCrop.png b/bindings/python/docs/source/_static/images/references/centerCrop.png new file mode 100644 index 000000000..5b34d4cbc Binary files /dev/null and b/bindings/python/docs/source/_static/images/references/centerCrop.png differ diff --git a/bindings/python/docs/source/_static/images/tutorials/isp.jpg b/bindings/python/docs/source/_static/images/tutorials/isp.jpg new file mode 100644 index 000000000..3ae088d3b Binary files /dev/null and b/bindings/python/docs/source/_static/images/tutorials/isp.jpg differ diff --git a/bindings/python/docs/source/_static/images/tutorials/multiple/setup.jpg b/bindings/python/docs/source/_static/images/tutorials/multiple/setup.jpg new file mode 100644 index 000000000..2d1b2b6eb Binary files /dev/null and b/bindings/python/docs/source/_static/images/tutorials/multiple/setup.jpg differ diff --git a/bindings/python/docs/source/_static/images/tutorials/windows/cmake.png b/bindings/python/docs/source/_static/images/tutorials/windows/cmake.png new file mode 100755 index 000000000..f563d6062 Binary files /dev/null and b/bindings/python/docs/source/_static/images/tutorials/windows/cmake.png differ diff --git a/bindings/python/docs/source/_static/images/tutorials/windows/execution_aliases.png b/bindings/python/docs/source/_static/images/tutorials/windows/execution_aliases.png new file mode 100755 index 000000000..a0de178d8 Binary files /dev/null and b/bindings/python/docs/source/_static/images/tutorials/windows/execution_aliases.png differ diff --git a/bindings/python/docs/source/_static/images/tutorials/windows/execution_search.png b/bindings/python/docs/source/_static/images/tutorials/windows/execution_search.png new file mode 100755 index 000000000..1492ef786 Binary files /dev/null and b/bindings/python/docs/source/_static/images/tutorials/windows/execution_search.png differ diff --git a/bindings/python/docs/source/_static/images/tutorials/windows/git.png b/bindings/python/docs/source/_static/images/tutorials/windows/git.png new file mode 100755 index 000000000..6ce08c194 Binary files /dev/null and b/bindings/python/docs/source/_static/images/tutorials/windows/git.png differ diff --git a/bindings/python/docs/source/_static/images/tutorials/windows/pip.png b/bindings/python/docs/source/_static/images/tutorials/windows/pip.png new file mode 100755 index 000000000..8b7490fe5 Binary files /dev/null and b/bindings/python/docs/source/_static/images/tutorials/windows/pip.png differ diff --git a/bindings/python/docs/source/_static/images/tutorials/windows/pip_success.png b/bindings/python/docs/source/_static/images/tutorials/windows/pip_success.png new file mode 100755 index 000000000..3c4f5fc98 Binary files /dev/null and b/bindings/python/docs/source/_static/images/tutorials/windows/pip_success.png differ diff --git a/bindings/python/docs/source/_static/images/tutorials/windows/powershell.png b/bindings/python/docs/source/_static/images/tutorials/windows/powershell.png new file mode 100755 index 000000000..314e3ba08 Binary files /dev/null and b/bindings/python/docs/source/_static/images/tutorials/windows/powershell.png differ diff --git a/bindings/python/docs/source/_static/images/tutorials/windows/store.png b/bindings/python/docs/source/_static/images/tutorials/windows/store.png new file mode 100755 index 000000000..74a92382e Binary files /dev/null and b/bindings/python/docs/source/_static/images/tutorials/windows/store.png differ diff --git a/bindings/python/docs/source/_static/images/tutorials/windows/vsstudio.png b/bindings/python/docs/source/_static/images/tutorials/windows/vsstudio.png new file mode 100755 index 000000000..fc64f3f2a Binary files /dev/null and b/bindings/python/docs/source/_static/images/tutorials/windows/vsstudio.png differ diff --git a/bindings/python/docs/source/_static/install_dependencies.sh b/bindings/python/docs/source/_static/install_dependencies.sh new file mode 100755 index 000000000..7298def5f --- /dev/null +++ b/bindings/python/docs/source/_static/install_dependencies.sh @@ -0,0 +1,267 @@ +#!/bin/bash + +trap 'RET=$? ; echo -e >&2 "\n\x1b[31mFailed installing dependencies. Could be a bug in the installer or unsupported platform. Open a bug report over at https://github.com/luxonis/depthai - exited with status $RET at line $LINENO \x1b[0m\n" ; +exit $RET' ERR + +readonly linux_pkgs=( + python3 + python3-pip + udev + cmake + git + python3-numpy +) + +readonly debian_pkgs=( + ${linux_pkgs[@]} + # https://docs.opencv.org/master/d7/d9f/tutorial_linux_install.html + build-essential + libgtk2.0-dev + pkg-config + libavcodec-dev + libavformat-dev + libswscale-dev + python3-dev + libtbb-dev + libjpeg-dev + libpng-dev + libtiff-dev + # https://stackoverflow.com/questions/55313610 + ffmpeg + libsm6 + libxext6 + python3-pyqt5 + python3-pyqt5.qtquick + qml-module-qtquick-controls2 + qml-module-qt-labs-platform + qtdeclarative5-dev + qml-module-qtquick2 + qtbase5-dev + qtchooser + qt5-qmake + qtbase5-dev-tools + qml-module-qtquick-layouts + qml-module-qtquick-window2 +) + +readonly debian_arm_pkgs=( + ${linux_pkgs[@]} + # https://docs.opencv.org/master/d7/d9f/tutorial_linux_install.html + build-essential + libgtk2.0-dev + pkg-config + libavcodec-dev + libavformat-dev + libswscale-dev + python3-dev + libtbb-dev + libjpeg-dev + libpng-dev + libtiff-dev + # https://stackoverflow.com/questions/55313610 + ffmpeg + libsm6 + libxext6 + python3-pyqt5 + python3-pyqt5.qtquick + qml-module-qtquick-controls2 + qml-module-qt-labs-platform + qtdeclarative5-dev + qml-module-qtquick2 + qtbase5-dev + qtchooser + qt5-qmake + qtbase5-dev-tools + qml-module-qtquick-layouts + qml-module-qtquick-window2 + # https://stackoverflow.com/a/53402396/5494277 + libhdf5-dev + libhdf5-dev + libatlas-base-dev + # https://github.com/EdjeElectronics/TensorFlow-Object-Detection-on-the-Raspberry-Pi/issues/18#issuecomment-433953426 + libilmbase-dev + libopenexr-dev + libgstreamer1.0-dev +) + +readonly debian_pkgs_pre22_04=( + libdc1394-22-dev + libgl1-mesa-glx + libtbb2 + +) +readonly debian_pkgs_post22_04=( + libdc1394-dev + libgl1-mesa-glx + libtbbmalloc2 + +) +readonly debian_pkgs_23=( + libdc1394-dev + libgl1-mesa-dev + libtbbmalloc2 +) + + +readonly fedora_pkgs=( + ${linux_pkgs[@]} + gtk2-devel + # Fedora uses pkgconf instead of pkg-config + tbb-devel + libjpeg-turbo-devel + libpng-devel + libtiff-devel + libdc1394-devel + # TODO(PM): ffmpeg requires enabling rpmfusion-free-updates + # TODO(PM): libavcodec-dev libavformat-dev libswscale-dev python-dev libtbb2 + # libsm6 libxext6 libgl1-mesa-glx +) + +print_action () { + green="\e[0;32m" + reset="\e[0;0m" + printf "\n$green >>$reset $*\n" +} +print_and_exec () { + print_action $* + $* +} + +version_lte() { + [[ "$1" == "$(echo -e "$1\n$2" | sort -V | head -n1)" ]] +} + +declare -A debian_versions=( + ["trixie/sid"]="13" + ["bookworm/sid"]="12" + ["bullseye/sid"]="11" + ["buster/sid"]="10" + ["stretch/sid"]="9" + ["jessie/sid"]="8" + ["wheezy/sid"]="7" + ["squeeze/sid"]="6" +) + +# Function to lookup and print Debian version number +lookup_debian_version_number() { + debian_version_string="$1" + version_number="${debian_versions[$debian_version_string]}" + + if [ -n "$version_number" ]; then + echo "$version_number" + else + echo "None" + fi +} + +if [[ $(uname) == "Darwin" ]]; then + echo "During Homebrew install, certain commands need 'sudo'. Requesting access..." + sudo true + homebrew_install_url="https://raw.githubusercontent.com/Homebrew/install/master/install.sh" + print_action "Installing Homebrew from $homebrew_install_url" + # CI=1 will skip some interactive prompts + CI=1 /bin/bash -c "$(curl -fsSL $homebrew_install_url)" + print_and_exec brew install git + echo + echo "=== Installed successfully! IMPORTANT: For changes to take effect," + echo "please close and reopen the terminal window, or run: exec \$SHELL" + +elif [ -f /etc/os-release ]; then + source /etc/os-release + if [ -f /etc/debian_version ]; then + output=$(cat /etc/debian_version) + echo $output + if [[ $output == *sid ]]; then + version=$(lookup_debian_version_number $output) + else + version=$output + fi + + # Correctly determine if the architecture is ARM or aarch64 + IS_ARM=false + if [[ $(uname -m) =~ ^arm* || $(uname -m) == "aarch64" ]]; then + IS_ARM=true + fi + + echo "$version" + echo "$IS_ARM" + + if [ $IS_ARM ]; then + sudo DEBIAN_FRONTEND=noninteractive apt install -y "${debian_arm_pkgs[@]}" + if [[ $version == 13* ]]; then + echo "Detected ARM Debian 13" + sudo apt install -y "${debian_pkgs_23[@]}" + elif version_lte "$version" "11.99"; then + echo "Using pre-22.04 ARM package list" + sudo apt-get install -y ${debian_pkgs_pre22_04[@]} + + # Check for uvcdynctrl package and recommend removal if found + if dpkg -s uvcdynctrl &> /dev/null; then + echo -e "\033[33mWe detected 'uvcdynctrl' installed on your system.\033[0m" + # Instructions for removal + echo -e "\033[33m$ sudo apt remove uvcdynctrl uvcdynctrl-data\033[0m" + echo -e "\033[33m$ sudo rm -f /var/log/uvcdynctrl-udev.log\033[0m" + fi + + + else + echo "Using post-22.04 ARM package list" + sudo apt-get install -y ${debian_pkgs_post22_04[@]} + fi + + # Add libjasper-dev for ARM but not aarch64 + [[ $(uname -m) =~ ^arm* ]] && { sudo apt install -y libjasper-dev; } + + else + sudo DEBIAN_FRONTEND=noninteractive apt install -y "${debian_pkgs[@]}" + if [[ $version == 13* ]]; then + echo "Detected Debian 13" + sudo apt install -y "${debian_pkgs_23[@]}" + elif version_lte "$version" "11.99"; then + echo "Using pre-22.04 package list" + sudo apt-get install -y "${debian_pkgs_pre22_04[@]}" + + else + echo "Using post-22.04 package list" + sudo apt-get install -y "${debian_pkgs_post22_04[@]}" + fi + fi + + # Check for uvcdynctrl package and recommend removal if found + if dpkg -s uvcdynctrl &> /dev/null; then + echo -e "\033[33mWe detected 'uvcdynctrl' installed on your system.\033[0m" + # Instructions for removal + echo -e "\033[33m$ sudo apt remove uvcdynctrl uvcdynctrl-data\033[0m" + echo -e "\033[33m$ sudo rm -f /var/log/uvcdynctrl-udev.log\033[0m" + fi + + + + if [ "$VERSION_ID" == "21.04" ]; then + echo -e "\033[33mThere are known issues with running our demo script on Ubuntu 21.04, due to package \"python3-pyqt5.sip\" not being in a correct version (>=12.9)\033[0m" + echo -e "\033[33mWe recommend installing the updated version manually using the following commands\033[0m" + echo -e "\033[33m$ wget http://mirrors.kernel.org/ubuntu/pool/universe/p/pyqt5-sip/python3-pyqt5.sip_12.9.0-1_amd64.deb\033[0m" + echo -e "\033[33m$ sudo dpkg -i python3-pyqt5.sip_12.9.0-1_amd64.deb\033[0m" + echo "" + fi + + + elif [[ "$ID" == "fedora" ]]; then + sudo dnf update -y + sudo dnf install -y "${fedora_pkgs[@]}" + sudo dnf groupinstall -y "Development Tools" "Development Libraries" + python3 -m pip install --upgrade pip + else + echo "ERROR: Distribution not supported" + exit 99 + fi + # Allow all users to read and write to Myriad X devices + echo "Installing udev rules..." + echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="03e7", MODE="0666"' | sudo tee /etc/udev/rules.d/80-movidius.rules > /dev/null + sudo udevadm control --reload-rules && sudo udevadm trigger +else + echo "ERROR: Host not supported" + exit 99 +fi + +echo "Finished installing global libraries." diff --git a/bindings/python/docs/source/_static/install_depthai.sh b/bindings/python/docs/source/_static/install_depthai.sh new file mode 100755 index 000000000..e36ee888a --- /dev/null +++ b/bindings/python/docs/source/_static/install_depthai.sh @@ -0,0 +1,247 @@ +#!/bin/bash + +APP_NAME="depthai" +WORKING_DIR_NAME="Luxonis" +WORKING_DIR="$HOME/$WORKING_DIR_NAME" +mkdir "$WORKING_DIR" +install_path="" +path_correct="false" + +trap 'RET=$? ; echo -e >&2 "\n\x1b[31mFailed installing dependencies. Could be a bug in the installer or unsupported platform. Open a bug report over at https://github.com/luxonis/depthai - exited with status $RET at line $LINENO \x1b[0m\n" ; exit $RET' ERR + +while [ "$path_correct" = "false" ] +do + echo "" + echo 'ENTER absolute installation path for depthai or leave empty and default path: $HOME will be used.' + read -e install_path < /dev/tty + echo "" + + if [ "$install_path" = "" ]; then + echo "Using default installation path: $WORKING_DIR" + mkdir -p "$WORKING_DIR" + else + echo "Using given installation path: $install_path" + WORKING_DIR="$install_path" + fi + + if [ -d "$WORKING_DIR" ]; then + echo "Directory: $WORKING_DIR is OK" + path_correct="true" + else + echo "Directory: $WORKING_DIR is not valid. Try again!" + fi +done + +DEPTHAI_DIR="$WORKING_DIR/$APP_NAME" +VENV_DIR="$WORKING_DIR/venv" +ENTRYPOINT_DIR="$DEPTHAI_DIR/entrypoint" + +# Get Python version or find out that python 3.10 must be installed +python_executable=$(which python3) +python_chosen="false" +install_python="false" +python_version=$(python3 --version) +python_version_number="" +if [[ "$python_version" != 'Python'* ]]; then + python_version="" +fi +echo "" + +# check default python version, offer it to the user or get another one +while [ "$python_chosen" = "false" ] +do + if [[ "$python_version" == "" ]]; then + echo "No python version found." + echo "Input path for python binary, version 3.8 or higher, or leave empty and python 3.10 will be installed for you." + echo "Press ENTER key to continue" + read -e python_binary_path < /dev/tty + # python not found and user wants to install python 3.10 + if [ "$python_binary_path" = "" ]; then + install_python="true" + python_chosen="true" + fi + else + # E.g Python 3.10 -> nr_1=3, nr_2=10, for Python 3.7.5 -> nr_1=r, nr_2=7 + nr_1="${python_version:7:1}" + nr_2=$(echo "${python_version:9:2}" | tr -d -c 0-9) + echo "Python version: $python_version found." + if [ "$nr_1" -gt 2 ] && [ "$nr_2" -gt 7 ]; then # first two digits of python version greater then 3.7 -> python version 3.8 or greater is allowed. + echo "If you want to use it for installation, press ENTER key, otherwise input path to python binary." + echo "Press ENTER key to continue" + read -e python_binary_path < /dev/tty + # user wants to use already installed python whose version is high enough + if [ "$python_binary_path" = "" ]; then + python_chosen="true" + fi + else + echo "This python version is not supported by depthai. Enter path to python binary version et least 3.8, or leave empty and python 3.10 will be installed automatically." + echo "Press ENTER key to continue" + read -e python_binary_path < /dev/tty + # python version is too low and user wants to install python 3.10 + if [ "$python_binary_path" = "" ]; then + install_python="true" + python_chosen="true" + fi + fi + fi + # User entered some path that should lead to python binary, save python --version output and the rest is dealt in the while loop logic. + if [ "$python_binary_path" != "" ]; then + python_executable="$python_binary_path" + python_version=$($python_binary_path --version) + if [[ "$python_version" != 'Python'* ]]; then + python_version="" + fi + fi +done + + +write_in_file () { + # just make sure only strings are appended which are not in there yet + # first arg is text to write, second arg is the file path + if ! grep -Fxq "$1" "$2" + then + echo "$1" >> "$2" + fi +} + +COMMENT='# Entry point for Depthai demo app, enables to run in terminal' +BASHRC="$HOME/.bashrc" +ZSHRC="$HOME/.zshrc" +ADD_ENTRYPOINT_TO_PATH='export PATH=$PATH'":$ENTRYPOINT_DIR" + +# add to .bashrc only if it is not in there already +write_in_file "$COMMENT" "$BASHRC" +write_in_file "$ADD_ENTRYPOINT_TO_PATH" "$BASHRC" + +if [ -f "$ZSHRC" ]; then + write_in_file "$COMMENT" "$ZSHRC" + write_in_file "$ADD_ENTRYPOINT_TO_PATH" "$ZSHRC" +fi + +if [[ $(uname -s) == "Darwin" ]]; then + echo _____________________________ + echo "Calling macOS_installer.sh" + echo _____________________________ + echo "Running macOS installer." + + echo "Installing global dependencies." + bash -c "$(curl -fL https://docs.luxonis.com/install_dependencies.sh)" + + echo "Upgrading brew." + brew update + + # clone depthai form git + if [ -d "$DEPTHAI_DIR" ]; then + echo "Demo app already downloaded. Checking out main and updating." + else + echo "Downloading demo app." + git clone https://github.com/luxonis/depthai.git "$DEPTHAI_DIR" + fi + cd "$DEPTHAI_DIR" + git fetch + git checkout main + git pull + + # install python 3.10 and python dependencies + brew update + + if [ "$install_python" == "true" ]; then + echo "installing python 3.10" + brew install python@3.10 + python_executable=$(which python3.10) + fi + + # pip does not have pyqt5 for arm + if [[ $(uname -m) == 'arm64' ]]; then + echo "Installing pyqt5 with homebrew." + brew install pyqt@5 + fi + + # create python virtual environment + echo "Creating python virtual environment in $VENV_DIR" + echo "$python_executable" + "$python_executable" -m venv "$VENV_DIR" + # activate environment + source "$VENV_DIR/bin/activate" + python -m pip install --upgrade pip + + # install launcher dependencies + # only on mac silicon point PYTHONPATH to pyqt5 installation via homebrew, otherwise install pyqt5 with pip + if [[ $(uname -m) == 'arm64' ]]; then + if [[ ":$PYTHONPATH:" == *":/opt/homebrew/lib/python3.10/site-packages:"* ]]; then + echo "/opt/homebrew/lib/python$nr_1.$nr_2/site-packages already in PYTHONPATH" + else + export "PYTHONPATH=/opt/homebrew/lib/python$nr_1.$nr_2/site-packages:"$PYTHONPATH + echo "/opt/homebrew/lib/pythonv$nr_1.$nr_2/site-packages added to PYTHONPATH" + fi + else + pip install pyqt5 + fi + + pip install packaging + +elif [[ $(uname -s) == "Linux" ]]; then + echo _____________________________ + echo "Calling linux_installer.sh" + echo _____________________________ + + echo "Updating sudo-apt." + sudo apt-get update + + echo "Installing global dependencies." + sudo wget -qO- https://docs.luxonis.com/install_dependencies.sh | bash + + echo -e '\nRunning Linux installer.' + + # clone depthai form git + if [ -d "$DEPTHAI_DIR" ]; then + echo "Demo app already downloaded. Checking out main and updating." + + else + echo "Downloading demo app." + git clone https://github.com/luxonis/depthai.git "$DEPTHAI_DIR" + fi + + cd "$DEPTHAI_DIR" + git fetch + git checkout main + git pull + + # install python 3.10 + if [ "$install_python" == "true" ]; then + echo "installing python 3.10" + + sudo yes "" | sudo add-apt-repository ppa:deadsnakes/ppa + sudo apt -y install python3.10 + sudo apt -y install python3.10-venv + python_executable=$(which python3.10) + fi + + echo "Creating python virtual environment in $VENV_DIR" + + machine=$(uname -m) + if [[ $machine != 'armv6l' && $machine != 'armv7l' && $machine != 'aarch64' && $machine != 'arm64' ]]; then + "$python_executable" -m venv "$VENV_DIR" + else + "$python_executable" -m venv "$VENV_DIR" --system-site-packages + fi + + source "$VENV_DIR/bin/activate" + python -m pip install --upgrade pip + + pip install packaging + + if [[ $machine != 'armv6l' && $machine != 'armv7l' && $machine != 'aarch64' && $machine != 'arm64' ]]; then + pip install pyqt5 + fi +else + echo "Error: Host $(uname -s) not supported." + exit 99 +fi + +echo -e '\n\n:::::::::::::::: INSTALATION COMPLETE ::::::::::::::::\n' +echo -e '\nTo run demo app write in terminal.' +echo "Press ENTER KEY to finish and run the demo app..." +read -n1 key < /dev/tty +echo "STARTING DEMO APP." +python "$DEPTHAI_DIR/launcher/launcher.py" -r "$DEPTHAI_DIR" diff --git a/bindings/python/docs/source/components/bootloader.rst b/bindings/python/docs/source/components/bootloader.rst new file mode 100644 index 000000000..68f4f199f --- /dev/null +++ b/bindings/python/docs/source/components/bootloader.rst @@ -0,0 +1,153 @@ +.. _components_bootloader: + +Bootloader +========== + +DepthAI bootloader is a small program which handles the booting process, either by **booting the flashed application** (see :ref:`Standalone mode`), +or by **initializing the OAK PoE camera** so DepthAI API can connect to it. OAK PoE cameras already come with factory bootloader flashed at the factory. + +Bootloader is bundled inside with the ``depthai`` library, so to eg. flash the newest bootloader, you should use the newest ``depthai`` library. + +Device Manager +############## + +``device_manager.py`` is a Python script that interfaces with device :ref:`Bootloader` and bootloader configuration. +It can be found at `depthai-python/utilities `__. + +.. image:: https://github.com/luxonis/depthai-python/assets/18037362/1de0d86f-58bf-4979-b7d0-5ca7723db599 + +About Device +------------ + +Allows you to select the device you want to connect to, and you see metadata of connected device. + +* First we have to select the device we want to connect (boot) to, you can select that using: + + * **Dropdown** which contains found device MX Ids. Dropdown will only get updated when starting the app. + * **Specify IP** button if your OAK PoE camera isn't in the same LAN. + * **Search** feature - a new window will show that has a table with all available cameras (either via USB port or on LAN - OAK PoEs), their MxId, name, and status. Clicking on a table row will select that device and boot to it. + +Configuration settings +---------------------- + +After you select a device that has bootloader flashed, you can also configure bootloader configuration. + +- If the device has **NETWORK bootloader flashed**, you will be able to set its static/dynamic IP/mask/gateway, DNS, MAC, etc. +- If the device has **USB bootloader flashed**, you will be able to set its USB max speed and USB timeout. + +After setting some values, you have to click on the ``Flash configuration`` button. You can also ``Clear configuration``, or ``View configuration`` (its JSON). + +.. figure:: https://github.com/luxonis/depthai-python/assets/18037362/4bced0ab-92fa-4a73-986f-4a3ba8848940 + + When flashing static IP, make sure to also set the gateway/mask + +Applications settings +--------------------- + +Useful when dealing with :ref:`Standalone mode` applications. + +- **Flash application**: Select DepthAI Application Package (``.dap``) you want to flash the device. Below is a code snippet that showcases how to create the dap file. +- **Remove application**: Removes/clears the flashed application from the device +- **Open device streaming application**: Starts streaming frames from all connected cameras on the device. + +.. code-block:: python + + import depthai as dai + pipeline = dai.Pipeline() + # ... add nodes to pipeline + dai.DeviceBootloader.saveDepthaiApplicationPackage( + './file.dap', # Where to save the .dap file + pipeline, # My pipeline + compress=True, # Compress the FW and assets. In my case, it went from 24MB -> 9.5MB + applicationName='myAppName' # Optional, so you know which app is flashed afterwards + ) + +Danger Zone +----------- + +.. warning:: + + This section can potentially soft-brick your device, so be careful when using it. + +To prevent soft-bricking, OAK devices (since 2023) have factory bootloader and user bootloader. If user flashes a corrupted user bootloader, it will fallback to using factory bootloader. When updating bootloader, +Device Manager will try to flash the user bootloader first, if flashed (factory) bootloader supports it. If it's not possible, it will flash the factory bootloader. + +* **Update Bootloader** button will flash the newest bootloader to the device. You can select AUTO, USB or NETWORK bootloader. + + * AUTO will select the connection type of bootloader with which the camera is currently connected to. If you are connected via USB (doing factory reset) to an OAK PoE camera, you shouldn't select AUTO, as it will flash USB bootloader. + * USB bootloader will try to boot the application that is stored on flash memory. If it can't find flashed application, it will just behave as normal USB OAK - so it will wait until a host computer initializes the application. + * NETWORK bootloader is used by the OAK PoE cameras, and is flashed at the factory. It handles network initialization so the OAK PoE cameras can be booted through the LAN. +* **Flash Factory Bootloader**: If you want to flash the factory bootloader, you can use this button. It will flash the factory bootloader, even if the user bootloader is already flashed. +* **Factory reset** will erase the whole flash content and re-flash it with only the USB or NETWORK bootloader. Flashed application (pipeline, assets) and bootloader configurations will be lost. +* **Boot into USB recovery mode** will force eg. OAK PoE camera to be available through the USB connector, even if its boot pins are set to PoE booting. It is mostly used by our firmware developers. + +Factory and User bootloader +########################### + +There are two types of bootloaders: + +- **Factory bootloader**: bootloader that is flashed in the factory. We don't recommend re-flashing this bootloader, as it is not meant to be edited by end users. +- **User bootloader**: bootloader that can be flashed by the user. If booting is unsuccessful (eg. gets corrupted when flashing), it will fallback to factory bootloader. + +USB devices don't support user bootloader. If device has User bootloader, it will be used by default. If user bootloader is not flashed, it will fallback to Factory bootloader. + +Boot switches +############# + +- **Boot from flash** - DIP switch: 0x03 (switches 5,6 ON) - used by OAK PoE and USB cameras when bootloader is installed. +- **Recovery mode for USB** - DIP switch: 0x16 (switches 2,4,5 ON) - to boot directly into USB mode, so camera waits for the host to connect to it via USB. + +.. figure:: https://user-images.githubusercontent.com/18037362/154956812-c3fcc961-af46-4dfd-8080-e15c8c6b43f0.png + + OAK-D-PoE with switches 2,4,5 ON, for the purpose of connecting to the device via USB. + +On newer versions of OAK devices we have 0 ohm resistors (see image below) instead of a DIP switch, which means OAK will boot into flash by default. These new devices +have the bootloader flashed, which handles the booting process. There's also an additional button on the baseboard that switches boot to recovery mode when +pressed, which can be useful if the bootloader hasn't yet been flashed (eg. early access devices). You need to press this button when powering the device (when booting +happens). + +.. image:: https://user-images.githubusercontent.com/18037362/207295832-613fae0a-c0ae-411e-b03b-8a4736f1bfc7.png + +API +### + +**DeviceBootloader** is a class to communicate with the bootloader. It is used to flash created :ref:`Pipeline`, depthai application package +or update the bootloader itself. + +.. code-block: cpp + + std::tuple flash(std::function progressCb, Pipeline& pipeline); + + std::tuple flashDepthaiApplicationPackage(std::function progressCb, std::vector package); + + std::tuple flashBootloader(std::function progressCb, std::string path = ""); + +progressCb parameter takes a callback function, which will be called each time an progress update occurs (rate limited to 1 second). This is mainly +used to inform the user of the current flashing progress. + +.. _DAP: + +DepthAI Application Package (.dap) +################################## + +**DepthAI application package** is a binary file format which stores sections of data. The purpose of this format is to be able to extract +individual sections and do OTA updates without requiring to update all data. Example: Between update 1 and 2 of users application, +Depthai firmware, Asset storage (50MiB neural network) and asset structure remained the same, but some additional processing nodes were added +to the pipeline. Instead of transferring the whole package, only Pipeline description can be sent and updated. + +Depthai application package (**.dap**) consists of: + +- SBR (512B header which describes sections of data) +- Depthai device firmware (section "__firmware") +- Pipeline description (section "pipeline") +- Assets structure (section "assets") +- Asset storage (section "asset_storage") + +MAC address +########### + +All OAK PoE cameras have a unique MAC address which is used to identify the device on the network. It is calculated from the +MxID of the device, see `logic here `__. +The MAC address is stored in the DeviceBootloader configuration. + +.. include:: ../includes/footer-short.rst diff --git a/bindings/python/docs/source/components/device.rst b/bindings/python/docs/source/components/device.rst new file mode 100644 index 000000000..0f2e74fc8 --- /dev/null +++ b/bindings/python/docs/source/components/device.rst @@ -0,0 +1,274 @@ +.. _components_device: + +Device +====== + +Device is an `OAK camera `__ or a RAE robot. On all of our devices there's a powerful Robotics Vision Core +(`RVC `__). The RVC is optimized for performing AI inference, CV operations, and +for processing sensory inputs (eg. stereo depth, video encoders, etc.). + +Device API +########## + +:code:`Device` object represents an OAK device. When starting the device, you have to upload a :ref:`Pipeline` to it, which will get executed on the VPU. +When you create the device in the code, firmware is uploaded together with the pipeline and other assets (such as NN blobs). + +.. code-block:: python + + pipeline = depthai.Pipeline() + + # Create nodes, configure them and link them together + + # Upload the pipeline to the device + with depthai.Device(pipeline) as device: + # Print MxID, USB speed, and available cameras on the device + print('MxId:',device.getDeviceInfo().getMxId()) + print('USB speed:',device.getUsbSpeed()) + print('Connected cameras:',device.getConnectedCameras()) + + # Input queue, to send message from the host to the device (you can receive the message on the device with XLinkIn) + input_q = device.getInputQueue("input_name", maxSize=4, blocking=False) + + # Output queue, to receive message on the host from the device (you can send the message on the device with XLinkOut) + output_q = device.getOutputQueue("output_name", maxSize=4, blocking=False) + + while True: + # Get a message that came from the queue + output_q.get() # Or output_q.tryGet() for non-blocking + + # Send a message to the device + cfg = depthai.ImageManipConfig() + input_q.send(cfg) + +Connect to specified device +########################### + +If you have multiple devices and only want to connect to a specific one, or if your OAK PoE camera is outside of your +subnet, you can specify the device (either with MxID, IP, or USB port name) you want to connect to. + +.. code-block:: python + + # Specify MXID, IP Address or USB path + device_info = depthai.DeviceInfo("14442C108144F1D000") # MXID + #device_info = depthai.DeviceInfo("192.168.1.44") # IP Address + #device_info = depthai.DeviceInfo("3.3.3") # USB port name + with depthai.Device(pipeline, device_info) as device: + # ... + +Host clock syncing +################## + +When depthai library connects to a device, it automatically syncs device's timestamp to host's timestamp. Timestamp syncing happens continuously at around 5 second intervals, +and can be configured via API (example script below). + +.. image:: /_static/images/components/device_timesync.jpg + +Device clocks are synced at below 500µs accuracy for PoE cameras, and below 200µs accuracy for USB cameras at 1σ (standard deviation) with host clock. + +.. image:: /_static/images/components/clock-syncing.png + +A graph representing the accuracy of the device clock with respect to the host clock. We had 3 devices connected (OAK PoE cameras), all were hardware synchronized using `FSYNC Y-adapter `__. +Raspberry Pi (the host) had an interrupt pin connected to the FSYNC line, so at the start of each frame the interrupt happened and the host clock was recorded. Then we compared frame (synced) timestamps with +host timestamps and computed the standard deviation. For the histogram above we ran this test for approximately 3 hours. + +.. code-block:: python + + # Configure host clock syncing example + + import depthai as dai + from datetime import timedelta + # Configure pipeline + with dai.Device(pipeline) as device: + # 1st value: Interval between timesync runs + # 2nd value: Number of timesync samples per run which are used to compute a better value + # 3rd value: If true partial timesync requests will be performed at random intervals, otherwise at fixed intervals + device.setTimesync(timedelta(seconds=5), 10, True) # (These are default values) + + +Multiple devices +################ + +If you want to use multiple devices on a host, check :ref:`Multiple DepthAI per Host`. + +Device queues +############# + +After initializing the device, you can create input/output queues that match :ref:`XLinkIn`/:ref:`XLinkOut` nodes in the pipeline. These queues will be located on the host computer (in RAM). + +.. code-block:: python + + pipeline = dai.Pipeline() + + xout = pipeline.createXLinkOut() + xout.setStreamName("output_name") + # ... + xin = pipeline.createXLinkIn() + xin.setStreamName("input_name") + # ... + with dai.Device(pipeline) as device: + + outputQueue = device.getOutputQueue("output_name", maxSize=5, blocking=False) + inputQueue = device.getInputQueue("input_name") + + outputQueue.get() # Read from the queue, blocks until message arrives + outputQueue.tryGet() # Read from the queue, returns None if there's no msg (doesn't block) + if outputQueue.has(): # Check if there are any messages in the queue + + +When you define an output queue, the device can push new messages to it at any time, and the host can read from it at any time. + + +Output queue - `maxSize` and `blocking` +####################################### + +When the host is reading very fast from the queue (inside `while True` loop), the queue, regardless of its size, will stay empty most of +the time. But as we add things on the host side (additional processing, analysis, etc), it may happen that the device will be pushing messages to +the queue faster than the host can read from it. And then the messages in the queue will start to increase - and both `maxSize` and `blocking` +flags determine the behavior of the queue in this case. Two common configurations are: + +.. code-block:: python + + with dai.Device(pipeline) as device: + # If you want only the latest message, and don't care about previous ones; + # When a new msg arrives to the host, it will overwrite the previous (oldest) one if it's still in the queue + q1 = device.getOutputQueue(name="name1", maxSize=1, blocking=False) + + + # If you care about every single message (eg. H264/5 encoded video; if you miss a frame, you will get artifacts); + # If the queue is full, the device will wait until the host reads a message from the queue + q2 = device.getOutputQueue(name="name2", maxSize=30, blocking=True) # Also default values (maxSize=30/blocking=True) + +We used `maxSize=30` just as an example, but it can be any `int16` number. Since device queues are on the host computer, memory (RAM) usually isn't that scarce, so `maxSize` wouldn't matter that much. +But if you are using a small SBC like RPI Zero (512MB RAM), and are streaming large frames (eg. 4K unencoded), you could quickly run out of memory if you set `maxSize` to a high +value (and don't read from the queue fast enough). + +Some additional information +--------------------------- + +- Queues are thread-safe - they can be accessed from any thread. +- Queues are created such that each queue is its own thread which takes care of receiving, serializing/deserializing, and sending the messages forward (same for input/output queues). +- The :code:`Device` object isn't fully thread-safe. Some RPC calls (eg. :code:`getLogLevel`, :code:`setLogLevel`, :code:`getDdrMemoryUsage`) will get thread-safe once the mutex is set in place (right now there could be races). + +Watchdog +######## + +The watchdog is a crucial component in the operation of POE (Power over Ethernet) devices with DepthAI. When DepthAI disconnects from a POE device, the watchdog mechanism is the first to respond, +initiating a reset of the camera. This reset is followed by a complete system reboot, which includes the loading of the DepthAI bootloader and the initialization of the entire networking stack. + +The watchdog process is necessary to make the camera available for reconnection and **typically takes about 10 seconds**, which means the fastest possible reconnection time is 10 seconds. + + +Customizing the Watchdog Timeout +-------------------------------- + +.. tabs:: + + .. tab:: **Linux/MacOS** + + Set the environment variables `DEPTHAI_WATCHDOG_INITIAL_DELAY` and `DEPTHAI_BOOTUP_TIMEOUT` to your desired timeout values (in milliseconds) as follows: + + .. code-block:: bash + + DEPTHAI_WATCHDOG_INITIAL_DELAY= DEPTHAI_BOOTUP_TIMEOUT= python3 script.py + + .. tab:: **Windows PowerShell** + + For Windows PowerShell, set the environment variables like this: + + .. code-block:: powershell + + $env:DEPTHAI_WATCHDOG_INITIAL_DELAY= + $env:DEPTHAI_BOOTUP_TIMEOUT= + python3 script.py + + .. tab:: **Windows CMD** + + In Windows CMD, you can set the environment variables as follows: + + .. code-block:: guess + + set DEPTHAI_WATCHDOG_INITIAL_DELAY= + set DEPTHAI_BOOTUP_TIMEOUT= + python3 script.py + +Alternatively, you can set the timeout directly in your code: + +.. code-block:: python + + pipeline = depthai.Pipeline() + + # Create a BoardConfig object + config = depthai.BoardConfig() + + # Set the parameters + config.watchdogInitialDelayMs = + config.watchdogTimeoutMs = + + pipeline.setBoardConfig(config) + +By adjusting these settings, you can tailor the watchdog functionality to better suit your specific requirements. + + +Environment Variables +##################### + +The following table lists various environment variables used in the system, along with their descriptions: + +.. list-table:: + :widths: 50 50 + :header-rows: 1 + + * - Environment Variable + - Description + * - `DEPTHAI_LEVEL` + - Sets logging verbosity, options: 'trace', 'debug', 'warn', 'error', 'off' + * - `XLINK_LEVEL` + - Sets logging verbosity of XLink library, options: 'debug', 'info', 'warn', 'error', 'fatal', 'off' + * - `DEPTHAI_INSTALL_SIGNAL_HANDLER` + - Set to 0 to disable installing Backward signal handler for stack trace printing + * - `DEPTHAI_WATCHDOG` + - Sets device watchdog timeout. Useful for debugging (DEPTHAI_WATCHDOG=0), to prevent device reset while the process is paused. + * - `DEPTHAI_WATCHDOG_INITIAL_DELAY` + - Specifies delay after which the device watchdog starts. + * - `DEPTHAI_SEARCH_TIMEOUT` + - Specifies timeout in milliseconds for device searching in blocking functions. + * - `DEPTHAI_CONNECT_TIMEOUT` + - Specifies timeout in milliseconds for establishing a connection to a given device. + * - `DEPTHAI_BOOTUP_TIMEOUT` + - Specifies timeout in milliseconds for waiting the device to boot after sending the binary. + * - `DEPTHAI_PROTOCOL` + - Restricts default search to the specified protocol. Options: any, usb, tcpip. + * - `DEPTHAI_DEVICE_MXID_LIST` + - Restricts default search to the specified MXIDs. Accepts comma separated list of MXIDs. Lists filter results in an "AND" manner and not "OR" + * - `DEPTHAI_DEVICE_ID_LIST` + - Alias to MXID list. Lists filter results in an "AND" manner and not "OR" + * - `DEPTHAI_DEVICE_NAME_LIST` + - Restricts default search to the specified NAMEs. Accepts comma separated list of NAMEs. Lists filter results in an "AND" manner and not "OR" + * - `DEPTHAI_DEVICE_BINARY` + - Overrides device Firmware binary. Mostly for internal debugging purposes. + * - `DEPTHAI_BOOTLOADER_BINARY_USB` + - Overrides device USB Bootloader binary. Mostly for internal debugging purposes. + * - `DEPTHAI_BOOTLOADER_BINARY_ETH` + - Overrides device Network Bootloader binary. Mostly for internal debugging purposes. + +Reference +######### + +.. tabs:: + + .. tab:: Python + + .. autoclass:: depthai.Device + :members: + :inherited-members: + :noindex: + + .. tab:: C++ + + .. doxygenclass:: dai::Device + :project: depthai-core + :members: + :private-members: + :undoc-members: + +.. include:: ../includes/footer-short.rst diff --git a/bindings/python/docs/source/components/messages.rst b/bindings/python/docs/source/components/messages.rst new file mode 100644 index 000000000..7130d0147 --- /dev/null +++ b/bindings/python/docs/source/components/messages.rst @@ -0,0 +1,62 @@ +.. _components_messages: + +Messages +======== + +Messages are sent between linked :ref:`Nodes`. The only way nodes communicate with each other is by sending messages from one to another. On the +table of contents (left side of the page) **all DepthAI messages are listed** under the :code:`Messages` entry. You can click on them to find out more. + +.. rubric:: Creating a message in Script node + +A DepthAI message can be created either on the device, by a node automatically or manually inside the :ref:`Script` node. In below example, +the code is taken from the :ref:`Script camera control` example, where :ref:`CameraControl` is created inside the Script node every second +and sent to the :ref:`ColorCamera`'s input (:code:`cam.inputControl`). + +.. code-block:: python + + script = pipeline.create(dai.node.Script) + script.setScript(""" + # Create a message + ctrl = CameraControl() + # Configure the message + ctrl.setCaptureStill(True) + # Send the message from the Script node + node.io['out'].send(ctrl) + """) + +.. rubric:: Creating a message on a Host + +It can also be created on a host computer and sent to the device via :ref:`XLinkIn` node. :ref:`RGB Camera Control`, :ref:`Video & MobilenetSSD` +and :ref:`Stereo Depth from host` code examples demonstrate this functionality perfectly. In the example below, we have removed all the code +that isn't relevant to showcase how a message can be created on the host and sent to the device via XLink. + +.. code-block:: python + + # Create XLinkIn node and configure it + xin = pipeline.create(dai.node.XLinkIn) + xin.setStreamName("frameIn") + xin.out.link(nn.input) # Connect it to NeuralNetwork's input + + with dai.Device(pipeline) as device: + # Create input queue, which allows you to send messages to the device + qIn = device.getInputQueue("frameIn") + # Create ImgFrame message + img = dai.ImgFrame() + img.setData(frame) + img.setWidth(300) + img.setHeight(300) + qIn.send(img) # Send the message to the device + +.. rubric:: Creating a message on an external MCU + +A message can also be created on an external MCU and sent to the device via :ref:`SPIIn` node. An demo of such functionality is the +`spi_in_landmark `__ example. + +.. toctree:: + :maxdepth: 0 + :hidden: + :glob: + + messages/* + +.. include:: ../includes/footer-short.rst diff --git a/bindings/python/docs/source/components/messages/buffer.rst b/bindings/python/docs/source/components/messages/buffer.rst new file mode 100644 index 000000000..551d496a4 --- /dev/null +++ b/bindings/python/docs/source/components/messages/buffer.rst @@ -0,0 +1,26 @@ +Buffer +====== + +Just a good old buffer. All other messages derive from the :code:`Buffer` class. + +Reference +######### + +.. tabs:: + + .. tab:: Python + + .. autoclass:: depthai.Buffer + :members: + :inherited-members: + :noindex: + + .. tab:: C++ + + .. doxygenclass:: dai::Buffer + :project: depthai-core + :members: + :private-members: + :undoc-members: + +.. include:: ../../includes/footer-short.rst diff --git a/bindings/python/docs/source/components/messages/camera_control.rst b/bindings/python/docs/source/components/messages/camera_control.rst new file mode 100644 index 000000000..05d181840 --- /dev/null +++ b/bindings/python/docs/source/components/messages/camera_control.rst @@ -0,0 +1,35 @@ +CameraControl +============= + +This message is used for controlling the :ref:`color camera ` as well as the :ref:`mono camera `. +The message handles things like capturing still images, configuring auto focus, anti banding, white balance, +scenes, effects etc. + +Examples of functionality +######################### + +- :ref:`RGB Camera Control` +- :ref:`Mono Camera Control` +- :ref:`Auto Exposure on ROI` + +Reference +######### + +.. tabs:: + + .. tab:: Python + + .. autoclass:: depthai.CameraControl + :members: + :inherited-members: + :noindex: + + .. tab:: C++ + + .. doxygenclass:: dai::CameraControl + :project: depthai-core + :members: + :private-members: + :undoc-members: + +.. include:: ../../includes/footer-short.rst diff --git a/bindings/python/docs/source/components/messages/edge_detector_config.rst b/bindings/python/docs/source/components/messages/edge_detector_config.rst new file mode 100644 index 000000000..dd1aae70e --- /dev/null +++ b/bindings/python/docs/source/components/messages/edge_detector_config.rst @@ -0,0 +1,32 @@ +EdgeDetectorConfig +================== + +This message is used to configure the :ref:`EdgeDetector` node. +You can set the horizontal and vertical Sobel filter kernel. + +Examples of functionality +######################### + +- :ref:`Edge detector` + +Reference +######### + +.. tabs:: + + .. tab:: Python + + .. autoclass:: depthai.EdgeDetectorConfig + :members: + :inherited-members: + :noindex: + + .. tab:: C++ + + .. doxygenclass:: dai::EdgeDetectorConfig + :project: depthai-core + :members: + :private-members: + :undoc-members: + +.. include:: ../../includes/footer-short.rst diff --git a/bindings/python/docs/source/components/messages/feature_tracker_config.rst b/bindings/python/docs/source/components/messages/feature_tracker_config.rst new file mode 100644 index 000000000..053409c1f --- /dev/null +++ b/bindings/python/docs/source/components/messages/feature_tracker_config.rst @@ -0,0 +1,27 @@ +FeatureTrackerConfig +==================== + +This message is used to configure the :ref:`FeatureTracker` node. +You can set the CornerDetector, FeatureMaintainer and MotionEstimator. + +Reference +######### + +.. tabs:: + + .. tab:: Python + + .. autoclass:: depthai.FeatureTrackerConfig + :members: + :inherited-members: + :noindex: + + .. tab:: C++ + + .. doxygenclass:: dai::FeatureTrackerConfig + :project: depthai-core + :members: + :private-members: + :undoc-members: + +.. include:: ../../includes/footer-short.rst diff --git a/bindings/python/docs/source/components/messages/image_manip_config.rst b/bindings/python/docs/source/components/messages/image_manip_config.rst new file mode 100644 index 000000000..5535536f5 --- /dev/null +++ b/bindings/python/docs/source/components/messages/image_manip_config.rst @@ -0,0 +1,35 @@ +ImageManipConfig +================ + +This message can is used for cropping, warping, rotating, resizing, etc. an image in runtime. +It can be sent from host/:ref:`Script` node to either :ref:`ColorCamera` or :ref:`ImageManip`. + +.. note:: This message will reconfigure the whole config of the node, meaning you need to set all settings, not just the setting you want to change. + +Examples of functionality +######################### + +- :ref:`RGB Camera Control` +- :ref:`RGB Rotate Warp` + +Reference +######### + +.. tabs:: + + .. tab:: Python + + .. autoclass:: depthai.ImageManipConfig + :members: + :inherited-members: + :noindex: + + .. tab:: C++ + + .. doxygenclass:: dai::ImageManipConfig + :project: depthai-core + :members: + :private-members: + :undoc-members: + +.. include:: ../../includes/footer-short.rst diff --git a/bindings/python/docs/source/components/messages/img_detections.rst b/bindings/python/docs/source/components/messages/img_detections.rst new file mode 100644 index 000000000..afca0df55 --- /dev/null +++ b/bindings/python/docs/source/components/messages/img_detections.rst @@ -0,0 +1,34 @@ +ImgDetections +============= + +Both :ref:`YoloDetectionNetwork` and :ref:`MobileNetDetectionNetwork` output this message. This message contains a list of :code:`detections`, +which contains :code:`label`, :code:`confidence`, and the bounding box information (:code:`xmin`, :code:`ymin`, :code:`xmax`, :code:`ymax`). + +Examples of functionality +######################### + +- :ref:`RGB & MobilenetSSD` +- :ref:`Mono & MobilenetSSD` +- :ref:`RGB & Tiny YOLO` + +Reference +######### + +.. tabs:: + + .. tab:: Python + + .. autoclass:: depthai.ImgDetections + :members: + :inherited-members: + :noindex: + + .. tab:: C++ + + .. doxygenclass:: dai::ImgDetections + :project: depthai-core + :members: + :private-members: + :undoc-members: + +.. include:: ../../includes/footer-short.rst diff --git a/bindings/python/docs/source/components/messages/img_frame.rst b/bindings/python/docs/source/components/messages/img_frame.rst new file mode 100644 index 000000000..ac7302515 --- /dev/null +++ b/bindings/python/docs/source/components/messages/img_frame.rst @@ -0,0 +1,34 @@ +ImgFrame +======== + +These are all the images (regardless of their encoding/format), as well as the depth/disparity "image". :ref:`ColorCamera` and +:ref:`MonoCamera` are the source of the image frame messages. + +Examples of functionality +######################### + +- :ref:`RGB Preview` +- :ref:`Mono Preview` +- :ref:`Depth Preview` + +Reference +######### + +.. tabs:: + + .. tab:: Python + + .. autoclass:: depthai.ImgFrame + :members: + :inherited-members: + :noindex: + + .. tab:: C++ + + .. doxygenclass:: dai::ImgFrame + :project: depthai-core + :members: + :private-members: + :undoc-members: + +.. include:: ../../includes/footer-short.rst diff --git a/bindings/python/docs/source/components/messages/imu_data.rst b/bindings/python/docs/source/components/messages/imu_data.rst new file mode 100644 index 000000000..caee03085 --- /dev/null +++ b/bindings/python/docs/source/components/messages/imu_data.rst @@ -0,0 +1,26 @@ +IMUData +======= + +IMU data message is created by the :ref:`IMU` node. + +Reference +######### + +.. tabs:: + + .. tab:: Python + + .. autoclass:: depthai.IMUData + :members: + :inherited-members: + :noindex: + + .. tab:: C++ + + .. doxygenclass:: dai::IMUData + :project: depthai-core + :members: + :private-members: + :undoc-members: + +.. include:: ../../includes/footer-short.rst diff --git a/bindings/python/docs/source/components/messages/message_group.rst b/bindings/python/docs/source/components/messages/message_group.rst new file mode 100644 index 000000000..e947ad67d --- /dev/null +++ b/bindings/python/docs/source/components/messages/message_group.rst @@ -0,0 +1,32 @@ +MessageGroup +============ + +The MessageGroup message type is a versatile container used in DepthAI pipelines to group together a map of arbitrary DepthAI messages. It serves as the primary output of the :ref:`Sync` node, effectively synchronizing various input streams, and acts as the input to the :ref:`MessageDemux` node for subsequent disaggregation and processing. + +Creating MessageGroup +##################### + +MessageGroup can be created automatically by the Sync node as it aligns and groups messages from different sources based on their timestamps. Alternatively, it can be manually constructed in a host application or within a :ref:`Script` node to create custom groupings of DepthAI messages. + +Reference +######### + +.. tabs:: + + .. tab:: Python + + .. autoclass:: depthai.MessageGroup + :members: + :inherited-members: + :noindex: + + .. tab:: C++ + + .. doxygenclass:: dai::MessageGroup + :project: depthai-core + :members: + :private-members: + :undoc-members: + + +.. include:: ../../includes/footer-short.rst diff --git a/bindings/python/docs/source/components/messages/nn_data.rst b/bindings/python/docs/source/components/messages/nn_data.rst new file mode 100644 index 000000000..cef6922ae --- /dev/null +++ b/bindings/python/docs/source/components/messages/nn_data.rst @@ -0,0 +1,33 @@ +NNData +====== + +This message carries tensors and its data. :ref:`NeuralNetwork` node outputs NNData. + +Creating NNData +############### + +You can also create this message on the host (`example here `__) +or :ref:`Script` node (:ref:`example here